Уровень сложности
Средний
Время на прочтение
8 мин
Количество просмотров 4.5K
Я часто пользуюсь конфигурацией при написании VBA макросов в Excel. Иногда она нужна в формах для сохранения настроек, иногда для сохранения каких-то получаемых в процессе выполнения макроса данных.
Долгое время я искал информацию о том как работать с конфигом в VBA.
Есть множество различных вариантов, от хранения конфигурации в коде, до выноса ее в отдельный файл.
Сегодня я хотел бы пошагово рассказать о том как я храню и обрабатываю конфигурацию макроса в книге Excel.
Создаем лист ConfigSheet
У меня под рукой был Excel 2010, но в данном случае версия не имеет значения.
Для начала создаем отдельный лист. Я назвал его config, но это не принципиально. Что же действительно принципиально, так это CodeName
листа:
Если вы вдруг не знали, листы документа Excel в VBA – это, ни что иное, как объект класса Worksheet
. Обращаемся к справке и видим у объекта Worksheet
необходимое свойство (перезаписать его программно, несмотря на Read-only, можно, но об этом в другой раз):
Чтобы было проще обращаться к нашему Config листу, меняем ему значение поля (Name) в свойствах (если у вас их нет, нажмите F4 или View -> Properties Window, а если у вас нет структуры с проектом, нажмите Ctrl+R или View -> Project Explorer).
Таким образом, мы дополнительно защищаемся от ошибки в случае изменения обычного имени листа, а так же получаем автокомплит.
Кстати, так как лист – это объект, мы можем обращаться так же к его методам, полям и свойствам через точку, как обычно:
Этим мы и воспользуемся, но об этом чуть позже.
Создаем ListObject
Итак, как вы уже догадались, всю информацию мы будем сохранять в таблицу, а именно в объект ListObject
.
Для этого на нашем листе создаем пустую таблицу с двумя столбцами Key
и Value
:
Теперь осталось в Конструкторе задать нашей таблице имя, и основа для хранения готова:
Получаем объект таблицы
Переходим к самому интересному. Писать код будем в модуле листа ConfigSheet
.
Для начала создадим необходимые гетеры:
Public Property Get Table() As ListObject
' Свойство Read-Only для объекта таблицы.
Set Table = Me.ListObjects("configTable")
End Property
Public Property Get Keys() As Range
' Свойство Read-Only для столбца ключей.
Set Keys = Me.Table.ListColumns(KeyColumn).DataBodyRange
End Property
Public Property Get Values() As Range
' Свойство Read-Only для столбца значений.
Set Values = Me.Table.ListColumns(ValueColumn).DataBodyRange
End Property
В свойство Table
помещаем нашу таблицу, в Keys
– столбец ключей, в Values
– столбец значений.
Для удобства обращения к столбцам (и чтобы не хардкодить), прописываем Enum
на уровне модуля:
Private Enum EConfigColumns
KeyColumn = 1
ValueColumn
End Enum
Сказал «не хардкодить» и захардкодил название таблицы 😀. Исправляюсь:
Option Explicit
Private Enum EConfigColumns
KeyColumn = 1
ValueColumn
End Enum
Private Const ConfigTable As String = "configTable"
Прописываем свойство Get Config
Осталось создать свойство Config
, через которое будем записывать, получать и обновлять значения в таблице.
Для начала прописываем получение значения по ключу:
Public Property Get Config(ByVal Key As Variant) As Variant
Dim i As Long
For i = 1 To Me.Keys.Rows.Count
If Key <> Me.Keys(i).Value Then GoTo NextKey
Config = Me.Values(i).Value: Exit Property
NextKey:
Next
End Property
Здесь все довольно просто – пробегаем циклом по ключам и сравниваем их с параметром Key
, передаваемым пользователем. Как только находим нужный ключ, возвращаем соответствующее значение.
Так как мы работаем напрямую с объектом Range
, это уже несколько замедляет работу макроса. Плюс ко всему, во время цикла макрос будет постоянно вызывать свойства Keys
и Values
чтобы получить их значения, что еще сильнее замедлит скорость выполнения.
Чтобы немного ускорить процесс и избежать постоянное обращение, можно создать переменные и передавать в них свойства:
Public Property Get Config(ByVal Key As Variant) As Variant
' Переменные, для хранения свойств.
Dim Keys As Range: Set Keys = Me.Keys
Dim Values As Range: Set Values = Me.Values
Dim i As Long
For i = 1 To Me.Keys.Rows.Count
If Key <> Me.Keys(i).Value Then GoTo NextKey
Config = Me.Values(i).Value: Exit Property
NextKey:
Next
End Property
Но это несколько загромождает код (а ведь у нас еще будет свойство Let
), поэтому воспользуемся UDT
(user defined type) и процедурой, которая будет его инициализировать.
Создаем тип TConfig
в который помещаем все наши ранее созданные свойства (кроме, собственно, Config
), а так же создаем приватную переменную This
на уровне модуля:
Option Explicit
Private Enum EConfigColumns
KeyColumn = 1
ValueColumn
End Enum
Private Const ConfigTable As String = "configTable"
Private Type TConfig
Table As ListObject
Keys As Range
Values As Range
End Type
Private This As TConfig
Очень важно чтобы и Type TConfig
и переменная This
были приватными, иначе на этапе компиляции возникнет ошибка.
Далее, прописываем небольшую процедуру InitThis
, для присваивания значений нашему типу:
Public Sub InitThis()
Set This.Table = Me.Table
Set This.Keys = Me.Keys
Set This.Values = Me.Values
End Sub
Теперь поправим свойство Config
:
Public Property Get Config(ByVal Key As Variant) As Variant
Me.InitThis
Dim i As Long
For i = 1 To This.Keys.Rows.Count
If Key <> This.Keys(i).Value Then GoTo NextKey
Config = This.Values(i).Value: Exit Property
NextKey:
Next
End Property
Лаконично, не так ли?
Прописываем свойство Let Config
С установлением значений чуть иначе:
Public Property Let Config(ByVal Key As Variant, ByVal RHS As Variant)
Me.InitThis
If This.Keys Is Nothing Then This.Table.ListRows.Add: Me.InitThis
Dim i As Long
Do Until Key = This.Keys(i).Value
i = i + 1
If i > This.Keys.Rows.Count Then This.Table.ListRows.Add: Exit Do
Loop
This.Keys(i).Value = Key
This.Values(i).Value = RHS
End Property
В параметры принимаем Key
и RHS
(Right Hand Side – по правую руку), для того чтобы можно было прописывать такую конструкцию:
ConfigSheet.Config("Key") = "Value"
В самом начале проверяем This.Keys
на Nothing
, т.к. если в таблице еще совсем нет значений, при попытке пробежаться циклом по столбцам выскочит ошибка.
Чтобы этого избежать, после проверки добавляем в таблицу пустую строку и заново инициализировать This
. Только после этого можно будет свободно проходить по столбцам циклом.
Подобную проверку добавляем и в Get
, но вместо добавления строки просто возвращаем сообщение «Нет данных в таблице конфигурации»:
Public Property Get Config(ByVal Key As Variant) As Variant
Me.InitThis
If This.Keys Is Nothing Then Config = "Нет данных в таблице конфигурации": Exit Property
Dim i As Long
For i = 1 To This.Keys.Rows.Count
If Key <> This.Keys(i).Value Then GoTo NextKey
Config = This.Values(i).Value: Exit Property
NextKey:
Next
End Property
Далее, так же как и в Get
части, циклом, только теперь Do Until
, пробегаем по ключам конфига. При достижении максимального индекса – добавляем в конце новую строку и выходим из цикла. В конце присваиваем ключ и значение в соответствующие ячейки.
Удаляем пустые строки
При первом обращении к таблице у нас появится пустая строка. Чтобы ее убрать (и вообще, на всякий случай, каждый раз проверять, нет ли пустых строк в таблице), пропишем небольшую процедуру:
Public Sub DeleteEmptyRows()
Me.InitThis
Dim i As Long
For i = This.Keys.Count To 1 Step -1
If (IsEmpty(This.Keys(i).Value) And IsEmpty(This.Values(i).Value)) _
Or (This.Keys(i).Value = vbNullString And This.Values(i).Value = vbNullString) Then This.Table.ListRows(i).Delete
Next
End Sub
и добавим ее в уже написанную Let
часть:
Public Property Let Config(ByVal Key As Variant, ByVal RHS As Variant)
Me.InitThis
If This.Keys Is Nothing Then This.Table.ListRows.Add: Me.InitThis
Dim i As Long
Do Until Key = This.Keys(i).Value
i = i + 1
If i > This.Keys.Rows.Count Then This.Table.ListRows.Add: Exit Do
Loop
This.Keys(i).Value = Key
This.Values(i).Value = RHS
Me.DeleteEmptyRows ' Проверяем на пустые строки.
End Property
Итоговый код
Исправил запись в Property Get Config
, спасибо за наводку @qyix7z.
Option Explicit
Private Enum EConfigColumns
KeyColumn = 1
ValueColumn
End Enum
Private Const ConfigTable As String = "configTable"
Private Type TConfig
Table As ListObject
Keys As Range
Values As Range
End Type
Private This As TConfig
Public Sub InitThis()
Set This.Table = Me.Table
Set This.Keys = Me.Keys
Set This.Values = Me.Values
End Sub
Public Property Get Table() As ListObject
' Свойство Read-Only для объекта таблицы.
Set Table = Me.ListObjects(ConfigTable)
End Property
Public Property Get Keys() As Range
' Свойство Read-Only для столбца ключей.
Set Keys = Me.Table.ListColumns(KeyColumn).DataBodyRange
End Property
Public Property Get Values() As Range
' Свойство Read-Only для столбца значений.
Set Values = Me.Table.ListColumns(ValueColumn).DataBodyRange
End Property
Public Property Get Config(ByVal Key As Variant) As Variant
Me.InitThis
If This.Keys Is Nothing Then Config = "Нет данных в таблице конфигурации": Exit Property
Dim i As Long
For i = 1 To This.Keys.Rows.Count
If Key = This.Keys(i).Value Then Config = This.Values(i).Value: Exit Property
Next
End Property
Public Property Let Config(ByVal Key As Variant, ByVal RHS As Variant)
Me.InitThis
If This.Keys Is Nothing Then This.Table.ListRows.Add: Me.InitThis
Dim i As Long
Do Until Key = This.Keys(i).Value
i = i + 1
If i > This.Keys.Rows.Count Then This.Table.ListRows.Add: Exit Do
Loop
This.Keys(i).Value = Key
This.Values(i).Value = RHS
Me.DeleteEmptyRows ' Проверяем на пустые строки.
End Property
Public Sub DeleteEmptyRows()
Me.InitThis
Dim i As Long
For i = This.Keys.Count To 1 Step -1
If (IsEmpty(This.Keys(i).Value) And IsEmpty(This.Values(i).Value)) _
Or (This.Keys(i).Value = vbNullString And This.Values(i).Value = vbNullString) Then This.Table.ListRows(i).Delete
Next
End Sub
Проверяем результат
Ну и наконец проверяем получившийся результат.
Записываем значение в конфиг:
Sub Test()
' Значение "Дневник VBAшника" записано в таблицу с ключом "ChanelName"
ConfigSheet.Config("ChanelName") = "Дневник VBAшника"
End Sub
Считываем значение:
Sub Test()
' Распечатает: "Дневник VBAшника"
Debug.Print ConfigSheet.Config("ChanelName")
End Sub
Меняем и считываем еще раз:
Sub Test()
ConfigSheet.Config("ChanelName") = "https://t.me/VBAn_Diary"
' Распечатает: "https://t.me/VBAn_Diary"
Debug.Print ConfigSheet.Config("ChanelName")
End Sub
Ну а дальше этот лист можно спрятать от глаз пользователей, защитить книгу и структуру, и спокойно работать с конфигом.
Уверен, что можно изменить подход и написать код иначе. Возможно у вас есть предложения или дополнения по статье. Буду рад любому отзыву. 🙂
На чтение 2 мин. Просмотров 18 Опубликовано 15.05.2021
Вики внесла несколько изменений в параметры конфигурации в Excel, которые отображаются на различных вкладках диалогового окна Параметры Excel. Она задается вопросом, есть ли способ сохранить эти настройки, когда она их изменила, чтобы их можно было загрузить в другую систему или выполнить резервное копирование.
Нет единого места, где хранятся настройки конфигурации Excel. , поэтому ответ на этот вопрос не так прост, как можно было бы надеяться. Некоторые настройки хранятся в файле XLB, поддерживаемом системой. Место хранения этого файла зависит от версии Excel, которую вы используете, и от того, как настроена ваша система. Вот, например, место, где он может храниться в системе:
c: Users AppData Roaming Microsoft Excel
Вы можно легко – в Windows – выполнить поиск файлов, оканчивающихся на XLB, и создать их резервные копии.
Другие параметры конфигурации хранятся в отдельных книгах, а другие параметры изменяются на лету на основе первая книга, которую вы открываете в Excel. Резервное копирование книг легко, но вам нужно будет выяснить, какие из них вы хотите сохранить, основываясь исключительно на параметрах конфигурации, на которые они могут повлиять.
Конечно, вы можете найти сторонние надстройки для Excel, которые можно использовать для сбора и сохранения всех параметров конфигурации; немного времени, проведенное с вашей любимой поисковой системой, может найти хороших кандидатов.
Конфигурации. Создание с помощью таблицы параметров
Таблица параметров позволяет создавать несколько конфигураций деталей или сборок путем задания параметров во встроенной таблице Microsoft Excel. Для этого на компьютере должна быть установлена программа Microsoft Excel 2000 или ее более поздняя версия. Таблица параметров сохраняется в документе модели, при этом у нее теряется связь с исходным файлом Excel.
Перед созданием таблицы параметров желательно переименовать размеры и элементы, поскольку стандартные имена L1 или Вытянуть3 малоинформативны. Для отображения имен размеров перейдите в Настройки > Настройки пользователя > раздел Общие > и отметьте флажок Отобразить наименования размеров.
Рис.1 Настройка отображения размеров
Создание таблицы параметров:
1. Выберите Вставка > Таблица параметров… Инициализируется создание новой таблицы проекта и запуск Microsoft Excel из SolidWorks.
2. Выполните двойной щелчок на размере, чтобы вставить его в таблицу параметров.
3. Выполните двойной щелчок на элементе, чтобы вставить его в таблицу параметров и получить возможность управлять его погашением.
4. При необходимости введите дополнительные имена конфигураций и параметров.
5. Щелкните мышью вне электронной таблицы, чтобы закрыть Excel и вернуться в SolidWorks.
Редактирование таблицы параметров
1. Выберите Правка > Таблица параметров… > Редактировать таблицу в новом окне, открывая таблицу параметров.
2. Внесите в таблицу параметров необходимые изменения.
3. Щелкните вне таблицы параметров для выхода из режима редактирования таблицы.
При редактировании таблицы параметров доступны все средства Excel по работе с данными:
— вставка и удаление строк и столбцов;
— перенос столбцов с помощью функций Вырезать, Вставить;
— группировка данных;
— создание и применение форматов.
Для удобного представления информации в таблице параметров удобно создавать и использовать собственные форматы данных. Для создания таких форматов выполните следующие действия:
— выделите в Excel ячейку c данными;
— правой кнопкой мыши вызовите контекстное меню и выберите пункт Формат ячеек…;
— перейдите на вкладку Число и в окне Числовые форматы выберите все форматы;
— в окне Тип создайте нужный вам формат (синтаксис, применяемый при создании форматов, можно посмотреть здесь).
Видеоурок «Создание таблицы параметров»
Выберите Вставка > Таблица параметров…Двойным щелчком выберите элементы и размеры, которые вы хотите редактировать в конфигурациях. Щелкните мышью вне таблицы параметров, чтобы закрыть таблицу.
Видеоурок «Редактирование таблицы параметров»
Выберите на вкладке Менеджера конфигураций пункт Таблица параметров, щелчком на правой кнопке мыши вызовите контекстное меню и выберите в нем пункт Редактировать таблицу в новом окне.
{quote}{login=Drony}{date=23.10.2007 02:47}{thema=Re: Расчет компьютерной конфигурации в Excel}{post}{quote}{login=Dan}{date=23.10.2007 12:26}{thema=Расчет компьютерной конфигурации в Excel}{post}Есть готовый Price . Из этого Price мне надо сделать следущие :
1.
http://img156.imageshack.us/img156/8607/naimenoq8.jpg
2.
http://img156.imageshack.us/img156/9084/price1me7.jpg
3.
http://img132.imageshack.us/my.php?image=price2au3.jpg
Вот мой Price который я бы хотел сделать также
http://www.doxyterra.com/doxy.zip?1193127920&PHPSESSID1=
Спасибо тем кто поможет{/post}{/quote}
последнюю ссылку я открыть так и не смог.
Но как я понял из вышесказанного — тебе нужно :
книга в которой 2-а листа. Лист1 — прайс, Лист2 — твоя табличка с выподающими списками по каждому оборудованию соответственно.Все это не проблема, но вот с прдтягиванием цен бутет немного сложно.
Если все верно, то скинь прайс — позырим, что можно сделать….{/post}{/quote}
вот оба Price
http://ifolder.ru/3846789
Там есть Расчет конфигурации