2016-05-10 3 views
0

В настоящее время я работаю над проектом VBA в Excel, где мне нужно разблокировать VBProject, а также заблокировать другой VBProject. До сих пор я делал это с помощью SendKeys, но я продолжаю читать, что это не хороший метод, и этот API лучше? (Например, в этой теме: Unprotect VBProject from VB code)Excel VBA: Почему API лучше, чем SendKeys?

Однако я не смог найти подробную информацию о том, почему во время моих исследований.

Может кто-нибудь рассказать мне, почему именно SendKeys плохой? Какие вещи могут пойти не так? (Обратите внимание, что моя последовательность SendKeys составляет максимум 1,5 секунды). Также, почему API лучше подходит?

Спасибо! :)

+2

SendKeys ненадежен, потому что он буквально отправляет команду в активное окно, и не всегда можно гарантировать, что это предназначенное окно. – ojf

+0

Итак, для API не важно, какое окно активно? – Sun

+1

Правильно. Это просто [отправка ключевых штрихов] (https://msdn.microsoft.com/en-us/library/office/ff821075.aspx) (как объясняется @ojf). И теперь представьте, что ваш код Excel запущен, и кто-то пытается получить некоторые просмотры, когда выполняется код ... нажатие клавиш и изменение активного окна в браузере. – Ralph

ответ

2

WinAPI использует такие вещи, как ручки окна (вы, возможно, видели hWnd в коде раньше?) Для таргетинга на определенное окно. После этого вы можете отправлять и получать сообщения в это окно независимо от состояния окна (активное/неактивное) и т. Д.

Вы работаете непосредственно с объектом, которым является способ программирования.

Метод SendKeys() просто эмулирует пользователь, нажимающий клавиши на клавиатуре, независимо от того, какое окно открыто и где - поэтому он естественно отправляет вывод любому активному объекту и может его получить.


Другой способ думать об этом

Если вы кодирования, чтобы поместить значение в ячейке на определенном листе в VBA вы можете сделать следующее:

Range("A1").Value = "Foo" 

Это все хорошо и хорошо, но предполагает, что лист, который мы хотим, является активным листом в тот момент времени. Если это не так, вместо этого будет занесена неправильная ячейка на неправильном листе. Это эффективно, что вы делаете с SendKeys()

Это с другой стороны:

Workbooks("Target Workbook.xlsx").Sheets("Target Sheet").Range("A1").Value = "Foo" 

Определяет точную ячейку, в точном листе, в точном книге, которую мы хотим целевой - так, если этот лист не активен в тот момент времени, тогда не беспокойтесь! Он все равно будет идти в нужном месте (это вроде того, что вы делаете с API)


Предостережение

Игра с WinAPI в VBA может быть рискованным, если вы не знаю, что вы делаете - код для этих методов предварительно скомпилирован во внешней библиотеке, что означает, что ваш обработчик ошибок VBE не будет использоваться. Если вы ошиблись с API, вы рискуете повредить свою книгу (или, что еще хуже, в зависимости от того, что вы на самом деле делаете).

Вы также должны посмотреть условную компиляцию в VBA, потому что вам нужно декларировать функции и параметры по-разному в зависимости от того, используете ли вы 32-разрядную или 64-разрядную версию.