Excel VBA: варианты в переменных массива - PullRequest
14 голосов
/ 22 сентября 2011

Вопрос по вариантам. Я понимаю, что варианты в Excel vba являются типом данных по умолчанию и также неэффективны (с точки зрения чрезмерного использования в больших приложениях). Однако я регулярно использую их для хранения данных в массивах, которые имеют несколько типов данных. Текущий проект, над которым я работаю, - это, по сути, задача, которая требует огромной оптимизации очень плохого кода (c.7000 строк) - и это заставило меня задуматься; есть ли способ обойти это?

объяснить; код часто хранит данные в переменных массива. Поэтому рассмотрим набор данных из 10 столбцов на 10000. Столбцы представляют собой несколько разных типов данных (строковые, двойные, целые, даты и т. Д.). Предполагая, что я хочу сохранить их в массиве, я бы обычно;

dim myDataSet(10,10000) as variant

Но мои знания говорят о том, что это будет действительно неэффективно с кодом, оценивающим каждый элемент, чтобы определить, какой это тип данных (когда на практике я знаю, что я ожидаю). Кроме того, я теряю контроль, который дает мне измерение отдельных типов данных. Итак, (предполагая, что первые 6 являются строками, следующие 4 дублируются для простоты объяснения сути), я мог бы;

dim myDSstrings(6,10000) as string
dim myDSdoubles(4,10000) as double

Это возвращает мне контроль и эффективность, но также немного неуклюже (на практике типы смешаны и различны), и я получаю нечетное количество элементов в каждом, и в итоге приходится назначать их индивидуально в коде - а не по массе). Итак, это случай;

myDSstrings(1,r) = cells(r,1)
myDSdoubles(2,r) = cells(r,2)
myDSstrings(2,r) = cells(r,3)
myDSstrings(3,r) = cells(r,4)
myDSdoubles(3,r) = cells(r,5)
..etc...

Что намного страшнее, чем;

myDataSet(c,r) = cells(r,c)

Так что - это заставило меня задуматься - Должно быть, я что-то здесь упускаю. Каков оптимальный способ хранения массива данных разных типов? Или, если предположить, что нет способа сделать это - что было бы наилучшим методом кодирования для хранения массива смешанных типов данных?

Ответы [ 2 ]

11 голосов
/ 22 сентября 2011

Никогда не оптимизируйте свой код без предварительного измерения. Вы можете быть удивлены, где код самый медленный. Я использую утилиту PerfMon от Professional Excel Development, но вы также можете использовать и свою собственную.

Чтение и запись в Excel-диапазоны и из них - большой расход времени. Хотя варианты могут тратить много памяти, это

Dim vaRange as Variant
vaRange = Sheet1.Range("A1:E10000").Value
'do something to the array
Sheet1.Range("A1:E10000").Value = vaRange

обычно быстрее, чем циклически проходить по строкам и ячейкам.

Мой предпочтительный метод использования массивов с несколькими типами данных - вообще не использовать массивы. Скорее я буду использовать пользовательский модуль класса и создаю свойства для элементов. Это не обязательно повышает производительность, но значительно облегчает написание и чтение кода.

4 голосов
/ 22 сентября 2011

Я не уверен, что ваше узкое место связано с типизацией массива Variant.

Кстати, чтобы установить значения из массива в диапазон Excel , вам следуетиспользуйте (в Excel 8 или выше):

Range("A1:B2") = myArray

В предыдущих версиях вы должны использовать следующий код:

Sub SuperBlastArrayToSheet(TheArray As Variant, TheRange As Range)
  With TheRange.Parent.Parent 'the workbook the range is in
    .Names.Add Name:="wstempdata", RefersToR1C1:=TheArray
    With TheRange
      .FormulaArray = "=wstempdata"
      .Copy
      .PasteSpecial Paste:=xlValues
    End With
    .Names("wstempdata").Delete
  End With
End Sub

из этого источника , что вам следуетчитайте для оптимизации VBA.

Тем не менее, вы должны профилировать свое приложение , чтобы увидеть, где ваши узкие места.См. этот вопрос от Issun , чтобы помочь вам сравнить свой код.

...