Добрый день многоуважаемые форумчане. Наверняка подобные вопросы уже были, но не поверите - ни в гугле не здесь я не нашёл ничего подобного (возможно не так спрашивал). Итак, у меня есть очень-очень большой код, который работает хорошо. Но долго. Я хочу его оптимизировать. В этом коде есть очень много похожих действий, а именно: с помощью кода определённые формулы вставляются в ячейки, затем эти формулы превращаются в значения. Вот пример: [vba]
[/vba] Собственно, вопрос. Можно ли как-то избегать того, чтобы формулы вставлялись в ячейки, затем Excel пересчитывал, а затем заменять всё на значения? И сразу, вместо этих лишних шагов вставлять в нужный диапазон только значения, рассчитанные VBA? Вопрос касается не конкретно этого кода, а ВООБЩЕ! Во вложении пример с вышеуказанным кодом.
Заранее всем спасибо, кто откликнется.
Добрый день многоуважаемые форумчане. Наверняка подобные вопросы уже были, но не поверите - ни в гугле не здесь я не нашёл ничего подобного (возможно не так спрашивал). Итак, у меня есть очень-очень большой код, который работает хорошо. Но долго. Я хочу его оптимизировать. В этом коде есть очень много похожих действий, а именно: с помощью кода определённые формулы вставляются в ячейки, затем эти формулы превращаются в значения. Вот пример: [vba]
[/vba] Собственно, вопрос. Можно ли как-то избегать того, чтобы формулы вставлялись в ячейки, затем Excel пересчитывал, а затем заменять всё на значения? И сразу, вместо этих лишних шагов вставлять в нужный диапазон только значения, рассчитанные VBA? Вопрос касается не конкретно этого кода, а ВООБЩЕ! Во вложении пример с вышеуказанным кодом.
Можно ли как-то избегать того, чтобы формулы вставлялись в ячейки
Не можно, а НУЖНО Конкретно для ПОИСКПОЗ в VBA можно написать так [vba]
Код
WorksheetFunction.Match
[/vba]Но в данном раскладе Вам это не поможет. Вы бы написали конечную цель вывода на лист Temp1 результатов ПОИСКПОЗа. Зачем? Что дальше с этим делать? А так можно, например, вот таким образом написать [vba]
Код
Sub test() With Sheets("csv") 'для листа csv Set s_ = .Cells(1).SpecialCells(xlLastCell) 'нижняя правая ячейка используемого диапазона (аналог нажатия Контрл+Енд на листа) c0_ = 24 'первый столбец nc_ = s_.Column - c0_ + 1 'кол-во столбцов r0_ = 2 'первая строка nr_ = s_.Row - r0_ + 1 'кол-во строк z_ = .Cells(1, c0_) 'постоянная часть ar = .Cells(r0_, c0_).Resize(nr_, nc_) 'все данные в массив ReDim ar1(1 To nr_, 1 To nc_) 'пустой массив для результатов End With With Sheets("Temp2") 'для листа Temp2 nr1_ = .Range("AU" & .Rows.Count).End(3).Row 'последняя строка arskl = .Range("AU2").Resize(nr1_).Value 'данные из AU в массив (последнюю пустую ячейку тоже захватываем, это не ошибка) End With Set slov = CreateObject("Scripting.Dictionary") 'словарь With slov 'для него .CompareMode = 1 'регистр букв неважен For i = 1 To nr1_ - 1 'цикл по массиву arskl кроме последней пустой .Item(arskl(i, 1)) = i 'в словаре значения из arskl - ключи, а порядковые номера - элементы Next i For i = 1 To nr_ 'цикл по строкам массива ar For j = 1 To nc_ 'цикл по столбцам массива ar If ar(i, j) = "" Then 'если пусто, то Exit For 'по столбцу дальше не проверяем - выход из цикла j End If zz_ = z_ & ar(i, j) 'значение для проверки If .Exists(zz_) Then 'если оно есть в словаре ar1(i, j) = .Item(zz_) 'в массив ar1 пишем порядковый номер (элемент в словаре) End If Next j Next i End With With Sheets("Temp1") 'для листа Temp1 .Range(.Cells(2, 1), .Cells(2, 1).SpecialCells(xlLastCell)).ClearContents 'стираем всё, начиная с А2 .Cells(2, 1).Resize(nr_, nc_) = ar1 'вставляем массив ar1 End With End Sub
Можно ли как-то избегать того, чтобы формулы вставлялись в ячейки
Не можно, а НУЖНО Конкретно для ПОИСКПОЗ в VBA можно написать так [vba]
Код
WorksheetFunction.Match
[/vba]Но в данном раскладе Вам это не поможет. Вы бы написали конечную цель вывода на лист Temp1 результатов ПОИСКПОЗа. Зачем? Что дальше с этим делать? А так можно, например, вот таким образом написать [vba]
Код
Sub test() With Sheets("csv") 'для листа csv Set s_ = .Cells(1).SpecialCells(xlLastCell) 'нижняя правая ячейка используемого диапазона (аналог нажатия Контрл+Енд на листа) c0_ = 24 'первый столбец nc_ = s_.Column - c0_ + 1 'кол-во столбцов r0_ = 2 'первая строка nr_ = s_.Row - r0_ + 1 'кол-во строк z_ = .Cells(1, c0_) 'постоянная часть ar = .Cells(r0_, c0_).Resize(nr_, nc_) 'все данные в массив ReDim ar1(1 To nr_, 1 To nc_) 'пустой массив для результатов End With With Sheets("Temp2") 'для листа Temp2 nr1_ = .Range("AU" & .Rows.Count).End(3).Row 'последняя строка arskl = .Range("AU2").Resize(nr1_).Value 'данные из AU в массив (последнюю пустую ячейку тоже захватываем, это не ошибка) End With Set slov = CreateObject("Scripting.Dictionary") 'словарь With slov 'для него .CompareMode = 1 'регистр букв неважен For i = 1 To nr1_ - 1 'цикл по массиву arskl кроме последней пустой .Item(arskl(i, 1)) = i 'в словаре значения из arskl - ключи, а порядковые номера - элементы Next i For i = 1 To nr_ 'цикл по строкам массива ar For j = 1 To nc_ 'цикл по столбцам массива ar If ar(i, j) = "" Then 'если пусто, то Exit For 'по столбцу дальше не проверяем - выход из цикла j End If zz_ = z_ & ar(i, j) 'значение для проверки If .Exists(zz_) Then 'если оно есть в словаре ar1(i, j) = .Item(zz_) 'в массив ar1 пишем порядковый номер (элемент в словаре) End If Next j Next i End With With Sheets("Temp1") 'для листа Temp1 .Range(.Cells(2, 1), .Cells(2, 1).SpecialCells(xlLastCell)).ClearContents 'стираем всё, начиная с А2 .Cells(2, 1).Resize(nr_, nc_) = ar1 'вставляем массив ar1 End With End Sub
_Boroda_, в очередной раз Вам большое спасибо! Буду изучать этот объект. Особенно спасибо за пояснения "для чайников" в каждой строке - это облегчит обучение!!! А что касается пояснений, зачем именно так это работает - там очень сложный код, в примере был его кусок. Всю логику быстро не пояснишь...
_Boroda_, в очередной раз Вам большое спасибо! Буду изучать этот объект. Особенно спасибо за пояснения "для чайников" в каждой строке - это облегчит обучение!!! А что касается пояснений, зачем именно так это работает - там очень сложный код, в примере был его кусок. Всю логику быстро не пояснишь...master-dd