Наcколько я понял, LUCKY13 использует процедуру типа SUB, а не функцию типа FUNCTION. Отличия в том, что процедура работает побыстрее (как я думаю), но ее нельзя вызвать как функцию ячейки типа =getResult(....)
Функцию же можно вызвать так же, как и стандартную функцию EXCEL. Но она не может изменять другие ячейки, кроме той, их которой вызвана (значения функции возвращаются в ячейку вызова автоматически). И такую функцию можно копировать, но работает это медленно.
Конструкции вида
Dim Sheet1_WS, Sheet2_WS As Worksheet
Dim R_data As Variant
Set Sheet1_WS = Application.ThisWorkbook.Sheets(1)
R_data = Sheet1_WS.Range(Sheet1_WS.Cells(1, 1), Sheet1_WS.Cells(FinalRow, FinalColumn))
For i = 2 To FinalRow
If R_data(i, 3) <> 0 Then
....
я никогда не использовал, но попробовал только что в том файле. Время работы не изменилось.
А вот что можно сделать для ускорения - нужно загрузить данные с листа в память, типа массива. Но глобальных массивов в VBA нет, поэтому нужно создать классы для каждого нужного столбца, и массивы объявить внутри этих классов. А потом создать инстанции (экземпляры) нужных классов, один раз заполнить их, и далее просто вытаскивать значения из массивов при помощи метода, например getValue(n) где n - номер элемента в массиве (проще всего это может быть номер строки).
Вот код для классов
1. Класс
clsSheet для столбца
Option Explicit
Dim mas(arraySize) As Long
Public Function setValues(sheet As String, column As Long)
Dim i As Long
Dim value As Variant
'
For i = 1 To arraySize
On Error GoTo erro
value = Worksheets(sheet).Cells(i, column)
If IsNumeric(value) Then
mas(i) = value
End If
erro:
Next i
End Function
'
Public Function getValue(row As Long) As Long
getValue = mas(row)
End Function
Класс
clsMas для хранения объектов clsSheet:
Option Explicit
Dim classes(10) As clsSheet
Public Function setClass(classID As Long, sheet As String, Optional column = 0)
Dim cNew As clsSheet
Dim col As Long
'
If column = 0 Then
col = classID
Else
col = column
End If
Set cNew = New clsSheet
Call cNew.setValues(sheet, col)
Set classes(classID) = cNew
End Function
'
Public Function getClass(classID As Long) As clsSheet
Set getClass = classes(classID)
End Function
Ну и как эту хрень использовать
Set cMas = New clsMas - создание контейнера классов
Call cMas.setClass(
1, "SS1") - создание экземпляра класса для столбца
1, SS1 - название листа (sheet)
В функции getResult есть оператор
Set clasZ = cMas.getClass(1)
он нужен для создания 1-го столбца, где живут номера.
А вот тут вместо чтения с листа (оно закомментировано), читаем значения номера из класса.
' za = Worksheets(z.Worksheet.Name).Cells(i, 1)
za = clasZ.getValue(i)
Использование классов ускоряет расчеты примерно в 2 раза (на моем компе) по сравнению с перебором значений на листе. Но нужно в начале работы создать объект класса и заполнить его значениями с листа (процедура ausfullen). Причем если в столбец загнать другие данные, то опять нужно вызывать процедуру "ausfullen"