Я часто пользуюсь конфигурацией при написании VBA макросов в Excel. Иногда она нужна в формах для сохранения настроек, иногда для сохранения каких-то получаемых в процессе выполнения макроса данных. Долгое время я искал информацию о том как работать с конфигом в VBA.Есть множество различных вариантов, от хранения конфигурации в коде, до выноса ее в отдельный файл. Сегодня я хотел бы пошагово рассказать о том как я храню и обрабатываю конфигурацию макроса в книге Excel. У меня под рукой был Excel 2010, но в данном случае версия не имеет значения.  Для начала создаем отдельный лист. Я назвал его config, но это не принципиально. Что же действительно принципиально, так это CodeName листа: Если вы вдруг не знали, листы документа Excel в VBA – это, ни что иное, как объект класса Worksheet. Обращаемся к справке и видим у объекта Worksheet необходимое свойство (перезаписать его программно, несмотря на Read-only, можно, но об этом в другой раз): Чтобы было проще обращаться к нашему Config листу, меняем ему значение поля (Name) в свойствах (если у вас их нет, нажмите F4 или View -> Properties Window, а если у вас нет структуры с проектом, нажмите Ctrl+R или View -> Project Explorer). Таким образом, мы дополнительно защищаемся от ошибки в случае изменения обычного имени листа, а так же получаем автокомплит. Кстати, так как лист – это объект, мы можем обращаться так же к его методам, полям и свойствам через точку, как обычно: Этим мы и воспользуемся, но об этом чуть позже. Итак, как вы уже догадались, всю информацию мы будем сохранять в таблицу, а именно в объект ListObject.Для этого на нашем листе создаем пустую таблицу с двумя столбцами Key и Value: Теперь осталось в Конструкторе задать нашей таблице имя, и основа для хранения готова: Переходим к самому интересному. Писать код будем в модуле листа ConfigSheet.Для начала создадим необходимые гетеры: В свойство Table помещаем нашу таблицу, в Keys – столбец ключей, в Values – столбец значений. Для удобства обращения к столбцам (и чтобы не хардкодить), прописываем Enum на уровне модуля: Сказал "не хардкодить" и захардкодил название таблицы 😀. Исправляюсь: Осталось создать свойство Config, через которое будем записывать, получать и обновлять значения в таблице. Для начала прописываем получение значения по ключу: Здесь все довольно просто – пробегаем циклом по ключам и сравниваем их с параметром Key, передаваемым пользователем. Как только находим нужный ключ, возвращаем соответствующее значение. Так как мы работаем напрямую с объектом Range, это уже несколько замедляет работу макроса. Плюс ко всему, во время цикла макрос будет постоянно вызывать свойства Keys и Values чтобы получить их значения, что еще сильнее замедлит скорость выполнения. Чтобы немного ускорить процесс и избежать постоянное обращение, можно создать переменные и передавать в них свойства: Но это несколько загромождает код (а ведь у нас еще будет свойство Let), поэтому воспользуемся UDT (user defined type) и процедурой, которая будет его инициализировать. Создаем тип TConfig в который помещаем все наши ранее созданные свойства (кроме, собственно, Config), а так же создаем приватную переменную This на уровне модуля: Очень важно чтобы и Type TConfig и переменная This были приватными, иначе на этапе компиляции возникнет ошибка. Далее, прописываем небольшую процедуру InitThis, для присваивания значений нашему типу: Теперь поправим свойство Config: Лаконично, не так ли? С установлением значений чуть иначе: В параметры принимаем Key и RHS (Right Hand Side – по правую руку), для того чтобы можно было прописывать такую конструкцию: ConfigSheet.Config("Key") = "Value" В самом начале проверяем This.Keys на Nothing, т.к. если в таблице еще совсем нет значений, при попытке пробежаться циклом по столбцам выскочит ошибка.Чтобы этого избежать, после проверки добавляем в таблицу пустую строку и заново инициализировать This. Только после этого можно будет свободно проходить по столбцам циклом.Подобную проверку добавляем и в Get, но вместо добавления строки просто возвращаем сообщение "Нет данных в таблице конфигурации": Далее, так же как и в Get части, циклом, только теперь Do Until, пробегаем по ключам конфига. При достижении максимального индекса – добавляем в конце новую строку и выходим из цикла. В конце присваиваем ключ и значение в соответствующие ячейки. При первом обращении к таблице у нас появится пустая строка. Чтобы ее убрать (и вообще, на всякий случай, каждый раз проверять, нет ли пустых строк в таблице), пропишем небольшую процедуру: и добавим ее в уже написанную Let часть: Исправил запись в Property Get Config, спасибо за наводку @qyix7z. Ну и наконец проверяем получившийся результат. Записываем значение в конфиг: Считываем значение: Меняем и считываем еще раз: Ну а дальше этот лист можно спрятать от глаз пользователей, защитить книгу и структуру, и спокойно работать с конфигом. Уверен, что можно изменить подход и написать код иначе. Возможно у вас есть предложения или дополнения по статье. Буду рад любому отзыву. 🙂  Музыкант