function LastRowIndex(byval w as worksheet, byval col as variant) as long
dim r as range
set r = application.intersect(w.usedrange, w.columns(col))
if not r is nothing then
set r = r.cells(r.cells.count)
if isempty(r.value) then
LastRowIndex = r.end(xlup).row
else
LastRowIndex = r.row
end if
end if
end function
Использование:
? LastRowIndex(ActiveSheet, 5)
? LastRowIndex(ActiveSheet, "AI")
Компоновщик встраивает в ваши модули ссылку на каждую используемую функцию API. когда загрузчик Windows загружает ваш исполняемый файл и его модули, ему необходимо «подключить» все вызовы вашего кода к тем местам в памяти, где фактически загружаются функции API. Если он не может их найти, он не будет продолжен.
Использование LoadLibrary
и GetProcAddress
является «стандартным» способом решения этой проблемы.
Использование двух DLL вам не помогут, потому что, пока одна из них не загрузится, ваше приложение все равно не запустится. Вы можете обойти это, используя отложенную загрузку, размещение всего кода, зависящего от новой ОС, в отдельном модуле и упаковка всех вызовов этого модуля в обработчики исключений Win32 SEH (вы получаете исключение SEH, когда задержка загрузки не может загрузить модуль). Преимущество заключается в том, что вы можете использовать «автоматическое» связывание без беспорядка указателей на функции, но обработка исключений может быть довольно неприятной.
В этой статье немного объясняется и дается несколько примеров того, как аккуратно обернуть это .
Почему Windows пытается найти SHLoadLibraryFromItem, даже если это не вызывается в XP?
Windows разрешает ссылки, когда приложение загружается в память, а не при выполнении вызова. Это называется «динамическое связывание» (в отличие от статического связывания с компоновщиком), но оно не является действительно динамическим. Следовательно, он не знает, будет ли вызван конкретный метод во время выполнения или нет.