Страницы: 1
RSS
Добавление массива в коллекцию.
 
Всем доброго времени суток.

Создаю пользовательский тип
Код
Private Type try
    nubm As String
    NameStruct As String
End Type
Создаю пользовательскую коллекцию.
Код
Dim col As Collection
Set col = New Collection
Добавить в коллекцию массив типа Integer я могу, а вот массив пользовательского типа - не получается.
Код
Private Sub Worksheet_Activate()
Dim t As try
Dim x As Integer
Dim m() As try

Dim col As Collection
Set col = New Collection
ReDim m(1 To 5)
For x = 1 To 5 Step 1
    m(x).NameStruct = "Проверка"
    m(x).nubm = x

    
Next
col.Add m
Erase m
    
End Sub

Это ограничение VBA, или я делаю, что-то не так?
 
да, ограничения, но обойти можно:
с классами нужно заморичиться
создайте в проекте модуль класса
назовите класс Try, на этом можно пока остановиться
выполните это:
Код
Private Sub Worksheet_Activate()
  Dim t As Try, col As Collection, art(1 To 5) As Try
  Set col = New Collection
  col.Add t
  col.Add mt
End Sub
ни в t, ни art ничего нет, зато их можно добавить в коллекцию
а дальше... чтобы с классом можно было работать нужно модуль класса Try наполнить хоть минимальным количеством кода (призвоение значений свойствам класса)

и название темы:
как добавить в коллекцию переменную, обьявленого пользователем типа, или массив таких переменных
Изменено: Ігор Гончаренко - 01.12.2018 21:16:28
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Я делаю по-другому
Код
Private Type try
    nubm As Collection
    NameStruct As Collection
End Type
 
А что, Вы не запомните, что на первой позиции слово, а на второй число? Зачем вообще этот Private Type?
Код
    Dim x As Integer
    Dim col As New Collection
    ReDim m(1 To 5, 1 To 2)
    For x = 1 To 5 Step 1
        m(x, 1) = "Проверка"
        m(x, 2) = x
    Next
    col.Add m
    Erase m
 
Цитата
Hugo написал:
Зачем вообще этот Private Type?
Читабельности кода ради :)
 
чтобы не держать в голове ерунды, не делать механических ошибок, когда 6-е поле - это доход, а 7-е - расход, а запись/чтение в файл / из файла - практически естесственный процесс.
очень легко вместо х(6) где-то в расчетах в запарке сунуть х(7)
и нужно быть довольно одаренным чтобы перепутать x.Plus и x.Minus
(только это все далеко от темы)
Изменено: Ігор Гончаренко - 01.12.2018 23:49:28
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Ігор Гончаренко написал:
когда 6-е поле - это доход
очень легко вместо х(6) где в расчетах в запарке сунуть х(7)
Ну можно ведь писать m(счётчик, доход) :)
Изменено: Hugo - 01.12.2018 23:46:30
 
Цитата
Ігор Гончаренко написал:
да, ограничения, но обойти можно:с классами нужно заморичиться
Спасибо за ответ.
Про классы я знал, но не хотелось создавать дополнительных модулей в проекте.

Оставлю как последнюю меру.
 
Цитата
Hugo написал:
А что, Вы не запомните, что на первой позиции слово, а на второй число? Зачем вообще этот Private Type?
Дело не в памяти, конечно для таких простых структур достаточно запомнить, но когда полей в структуре много - это уже не тривиальная задача.

Private Type - мне нужен для удобства.
Я написал это пример только для наглядности.
Код
Private Type sFilterData
' Структура описывающая поля фильтра
    Criteria_1 As String
    Criteria_2 As String
    Field As Variant
    Operator As Integer
    On As Boolean
    Count As Integer ' Счётчик хранит количество используемых критериев
    
End Type
Я хотел создать массив вот таких структур и добавить в коллекцию.
Изменено: Tipok - 02.12.2018 07:40:50
 
Проинформирую Вас как делаю я, а Вы решите сами надо это Вам или нет.
Как правило объявляю массив динамическим, например:
Код
Dim arr()
Структуру полей описываю константами-индексами столбцов, например:
Код
Const l_CRITERIA_1 As Long = 1 ' description field...
Const l_CRITERIA_2 As Long = l_CRITERIA_1 + 1 ' --"--"--"--"--"--"--
Const l_FIELD As Long = l_CRITERIA_2 + 1 ' --"--"--"--"--"--"--
Const l_OPERATOR As Long = l_FIELD + 1 ' --"--"--"--"--"--"--
Const l_ON As Long = l_OPERATOR + 1 ' --"--"--"--"--"--"--
Const l_COUNT As Long = l_ON + 1 ' --"--"--"--"--"--"--

' пограничные индексы для формирования границ массива по столбцам
Const l_1st_IDX As Long = l_CRITERIA_1 ' 1й индекс
Const l_LAST_IDX As Long = l_COUNT ' последний индекс
При известном кол-ве строк массива, например:
Код
ReDim arr(1 To 111, l_1st_IDX To l_LAST_IDX)

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Цитата
JayBhagavan написал:
Структуру полей описываю константами-индексами столбцов, например:
Спасибо за идею.

Так как попытка запихать массив пользовательских типов в коллекцию провалилась, придётся использовать двухмерные массивы.
Вы используете константы, а я подумываю использовать тип Enum.
 
Tipok, я думаю не проблема описанный мной подход реализовать для одномерного массива и его в качестве значения хранить в коллекции/словаре.
Цитата
Tipok написал: подумываю использовать тип Enum
Ваше право.

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Цитата
Tipok написал:
Спасибо за идею.
т.е.
Цитата
Hugo написал:
m(счётчик, доход)
не прошло... :)
 
Всем спасибо за подсказки. Решил использовать дополнительный массив структур в структуре Type StructFilter

Код
Private Type sFilterData' Структура описывающая поля фильтра
    Field As Integer ' Смещение от начала листа указывающее где нужно создать фильтр
    Criteria_1 As String
    Criteria_2 As String
    
    Operator As Integer
    On As Boolean
    Count As Integer ' Счётчик хранит количество используемых критериев
    
End Type

Private Type StructFilter
    EnableFilter As Boolean 'Значение True - Фильтр был активирован
    NameBook As String 'Имя книги из которой будут сохранены фильтры
    NameSheet As String 'Имя листа из которого будут сохранены фильтры
    RangeFilter As Range ' Диапазон применения фильтра
    
    arrData() As sFilterData
    
End Type
Dim sf As StructFilter

Ещё раз всем спасибо.
Пойду бороться с фильтрами.
Изменено: Tipok - 02.12.2018 12:08:12
Страницы: 1
Наверх