Советы тем, кто программирует на VB & VBA

Алексей Малинин, Ольга Павлова

Совет 423. Управление подключением макросов в приложениях Office

Совет 424. Использование цифровой подписи в Office 2000/XP

   Замечание для Office 2000

Совет 425. Идентификация элементов управления

Совет 426. Предотвращение многократного запуска VB-программы на одном компьютере

Совет 427. Удостоверьтесь, что используете нужный провайдер при создании структурированных наборов данных ADO

Совет 428. Программная реализация копирования экрана

Совет 429. Как открыть ниспадающее меню программным образом

Совет 430. Формирование кода цвета для HTML

Совет 431. Модернизация объекта Err

Совет 423. Управление подключением макросов в приложениях Office

В одной из Web-дискуссий был задан такой вопрос: «При загрузке Outlook у меня постоянно выдается окно предупреждения о наличии макросов в загружаемом проекте. Как мне добиться того, чтобы загрузка выполнялась автоматически без требования подтверждения в диалоговом окне?»

В целом решение этого вопроса одинаково для всех приложений Office. Но в отношении Outlook (версии 2000 и 2002) стоит напомнить, что эта программа использует для хранения макросов только один фиксированный файл с именем VbaProject.OTM, который хранится в каталоге C:\Windows\Application Data\Microsoft\Outlook\. Сам программный проект может иметь еще и собственное произвольное имя (оно видно только в среде VBA).

Для ответа на поставленный вопрос нужно иметь в виду, что приложения Office (начиная с 2000) имеют три уровня безопасности для управления загрузкой макросов, а также возможность использования цифровой подписи. С помощью этих механизмов можно более гибко управлять режимами загрузки.

Рассмотрим возможности управления безопасностью. Режим защиты устанавливается в диалоговом окне «Безопасность» (Security), которое открывается командой «Сервис|Макро|Безопасность» (рис. 1), где видно описание трех возможных уровней безопасности.

  1. Высокий. Разрешается запуск только подписанных макросов из надежных источников. Неподписанные макросы удаляются автоматически. При наличии макросов с неизвестными подписями выдается окно предупреждения, однако такие макросы можно подключить, только признав подлинность подписи.
  2. Средний. Подписанные макросы загружаются автоматически. О наличии неподписанных макросов выдается предупреждение, и решение об их загрузке принимается пользователем.
  3. Низкий. Защита отсутствует, все макросы загружаются автоматически.

В приложениях Office по умолчанию установлен средний уровень безопасности, что и вызывает появление окна предупреждения о наличии макросов. Соответственно существует два варианта ответа на приведенный выше вопрос:

  1. Установите низкий уровень безопасности — и никаких предупреждений вообще не будет. Но мы не рекомендуем этот вариант, так как проверка на наличие макросов при загрузке неизвестных файлов (например, полученных из Интернета или по электронной почте) необходима. Но для Outlook такой вариант является вполне подходящим — ведь мы имеем дело только с фиксированным файлом локального компьютера, который создается исключительно его хозяином.
  2. Лучший способ (наиболее универсальный) — использовать цифровую подпись проекта (в том числе и для Outlook). Этот способ немного подробнее мы рассмотрим в совете 424.

Для тех, кто работает с Word и Excel, есть еще один вариант, который позволяет отменить проверку наличия макросов в глобальных шаблонах и Add-ins. Для подобных приложений во вкладке Trusted Sources [Надежные источники] окна Security [Безопасность] имеется флажок Trust all installed Add-ins and templates [Доверять всем установленным надстройкам и шаблонам].

Под «установленными» подразумеваются дополнения и шаблоны, помещенные в каталог «Шаблоны пользователя». (Конкретное имя этого каталога указывается в поле User Templates [Шаблоны пользователя] во вкладке File Locations [Расположение] диалогового окна Tools|Options [Сервис|Параметры].)

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

В Word 97 такого специального режима для загрузки шаблонов не было. Но в начальной версии программы иногда имела место ошибка, когда шаблоны загружались без проверки на макрокод. Этот дефект уже давно устранен — заплатку, которая решает данную проблему, можно скачать по адресу http://www.microsoft.com/rus/download/wd97sp.htm.

В начало В начало

Совет 424. Использование цифровой подписи в Office 2000/XP

Здесь есть три элемента: создание и удаление сертификата, подключение цифровой подписи к документу, признание подписи в качестве «надежной». Рассмотрим их последовательно.

  1. Создание и удаление сертификата. Каждый пользователь может создать  один или несколько сертификатов. Это делается тремя способами: создать собственный сертификат, получить сертификат у администратора сети (если на предприятии разработаны собственные стандарты) и получить фирменный сертификат в специализированном центре (например, у той же компании Microsoft).

    Собственный сертификат создается утилитой SelfCert.exe, которая входит в состав пакета (рис. 2). В первом варианте русской версии MS Office 2000 в этой программе была ошибка (не раскрывалось диалоговое окно), но уже в первом сервисном наборе обновления дефект был исправлен.

  2. Удаление же сертификата выполняется довольно хитрым способом, с помощью (кто бы мог ожидать?) Internet Explorer. Для этого в IE нужно выбрать команду «Сервис|Свойства обозревателя», затем выделить вкладку «Содержание», нажать кнопку «Сертификатов...», открыть вкладку «Личные» в окне «Диспетчер Сертификатов» и уже там проводить операции с сертификатами (рис. 3).

  3. Подключение цифровой подписи. Электронная подпись подключается к VBA-проекту в среде VBA с помощью команды Tools|Digital Signature, которая выводит соответствующее окно «Цифровая подпись» (рис. 4).

    Для выбора нужного сертификата нужно нажать кнопку «Выбрать», после чего выдается окно Select Certificate со списком имеющихся сертификатов (рис. 5).

    Нажав кнопку, можно ознакомиться с более детальной информацией о сертификате в окне Certificate с тремя вкладками (рис. 6).

    К этой же информации можно получить доступ из других диалоговых окон при работе с сертификатами (обычно они называются «Подробности»). При желании можно в любой момент поменять подпись проекта или удалить ее совсем.

  4. Признание подписи в качестве надежной. Эта операция выполняется только в момент загрузки проекта с наличием макросов, имеющих подписи, в режиме среднего и высокого уровней безопасности.

    В этом случае выдается окно предупреждения (рис. 7).

    В этот момент можно посмотреть более детальную информацию о данном сертификате (кнопка Details). Если вы считаете данный источник надежным, то нужно установить флажок Always trust macros from this source [Всегда доверять макросам этого источника] — и данный сертификат автоматически попадет в список надежных. Эти можно увидеть во вкладке Trusted Source окна Security (рис. 8). Здесь же можно удалить ненужные подписи.

    Обратите внимание, что при использовании среднего уровня безопасности вы можете разрешить использование макросов проекта даже без занесения подписей в список доверенных (в том числе загружать проекты без подписей, например созданных в Office 97). При работе с высоким уровнем это можно сделать, только признав подпись (установив флажок «Всегда доверять»), то есть макросы проектов без подписей вообще нельзя использовать.

В начало В начало

Замечание для Office 2000

Следует обратить внимание еще на один важный момент, который имел место в приложениях Office 2000.

Порой здесь возникает ситуация, когда пользователь не может сохранить проект (документ с макрокодом) с электронной подписью — запись документа возможна только без подписи. При этом выдается неверная диагностика о нехватке места на диске.

Причина такого поведения — наличие внутренних синтаксических ошибок в коде проекта. Поэтому при обнаружении подобного сообщения о невозможности сохранения документа с электронной подписью, прежде чем отменять подпись, рекомендуем вам проверить работоспособность вашего кода. Довольно часто ошибка связана с отсутствием описания переменной или ссылки на внешний объект. Чтобы лучше понять суть ситуации, сделайте следующий простой пример в Word: создайте новый документ, перейдите в среду VBA и там создайте макрокоманду Test1:

Sub Test1 ()  
    Avar = 1  
End If  

Разумеется, сначала должен быть задан режим Option Explicit (обязательное объявление переменных).

Теперь установите электронную подпись и попробуйте сохранить документ. Скорее всего, у вас появится сообщение о нехватке места на диске для записи файла. Запустите макрокоманду Test1 на выполнение — транслятор выдаст сообщение о синтаксической ошибке (не определена переменная Avar). Добавьте в процедуру описание:

Dim Avar As Integer  

Теперь макрокоманда станет выполняться (правда, не делая ничего полезного), и документ тоже без проблем сохранится с электронной подписью.

Судя по всему, такое поведение Word 2000 является ошибкой (об этом говорит хотя бы выдача неверной диагностики). В Word 2002 эта ситуация исправлена — сохранение проекта с подписью выполняется независимо от ошибок кода.

В начало В начало

Совет 425. Идентификация элементов управления

Порой бывает необходимо узнать внутри программного кода тип элемента управления, с которым выполняется в данный момент работа. Например, вы хотите изменить текст на всех командных кнопках формы или изменить какие-то свойства элементов управления определенного типа. Для подобной идентификации лучше всего подходит оператор TypeOf, который может использоваться в операторе If...Then:

If TypeOf ctl Is CommandButton Then
  ' Выполнить что-то  
End If  
Для идентификации типа произвольного элемента управления можно использовать, например, такую процедуру:  
Private Sub Command1_Click()
  Dim ctl As Control
  Dim str As String
  For Each ctl In Me.Controls
    If TypeOf ctl Is CommandButton Then _
      str = "CommandButton"
    If TypeOf ctl Is TextBox Then str = "TextBox"
    If TypeOf ctl Is OptionButton Then str = _
      "OptionButton"
    If TypeOf ctl Is DriveListBox Then str = _
      "DriveListBox"
    If TypeOf ctl Is DataCombo Then str = _
      "DataCombo"
    MsgBox "Элемент управления типа " & str
  Next ctl
End Sub
В начало В начало

Совет 426. Предотвращение многократного запуска VB-программы на одном компьютере

Возможно, вам необходимо предотвратить возможность повторного запуска вашего приложения (если оно уже запущено). Для этого можно воспользоваться свойством PrevInstance объекта App, например таким образом:

Private Sub Main()
  If App.PrevInstance Then   
    ' приложение уже запущено
    Exit Sub ' завершить процедуру (а значит и приложение)
  End If  
  ' продолжение работы программы
End Sub  
В начало В начало

Совет 427. Удостоверьтесь, что используете нужный провайдер при создании структурированных наборов данных ADO

Как вы, возможно, знаете, технология ADO позволяет включать иерархические структуры данных в один объект Recordset. Однако при создании такого объекта нужно правильно указать опции провайдера. Например, типичный вариант формирования стандартного набора данных может использовать такую строку соединения:

"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyData\SomeDB.mdb"

Но для создания структурированного объекта Recordset вам нужно в качестве провайдера использовать SDataShape. К тому же вы должны указать, какой механизм OLEDB будет обеспечивать поддержку данных:

"Provider=MSDataShape;Data Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyData\SomeDB.mdb"

или в случае SQL Server users:

"Provider=MSDataShape;Data Provider=SQLOLEDB;Data Source=MyServerName;Initial    Catalog=SomeSQLDB"

Кроме того, можно указать подобную строку в свойстве Provider объекта ADO Connection.

В начало В начало

Совет 428. Программная реализация копирования экрана

Наш читатель Евгений спрашивает, как программным образом реализовать режим PrintScreen. А спустя пару дней сам же прислал свое решение этой задачи:

Private Declare Function BitBlt Lib "gdi32" _  
   (ByVal hDestDC As Long, ByVal x As Long, _  
    ByVal y As Long, ByVal nWidth As Long, _  
    ByVal nHeight As Long, ByVal hSrcDC As Long, _  
    ByVal xSrc As Long, ByVal ySrc As Long, _  
    ByVal dwRop As Long) As Long  
Private Declare Function GetDesktopWindow _  
    Lib "user32" () As Long  
Private Declare Function GetDC _  
    Lib "user32" (ByVal hwnd As Long) As Long  
Private Declare Function ReleaseDC Lib "user32" _  
    (ByVal hwnd As Long, ByVal hdc As Long) As Long  
Private Const SRCCOPY = &HCC0020  
'------------------------------------------------------------------------------------  
Private Sub Command1_Click()  
 Dim hwndScreen As Long  
 Dim hScreenDC As Long  
 Dim Res As Long  
 hwndScreen = GetDesktopWindow()  
 hScreenDC = GetDC(hwndScreen)  
 Res = BitBlt(hdc, 0, 0, ScaleWidth, ScaleHeight, hScreenDC, 0, 0, SRCCOPY)  
 Res = ReleaseDC(hwndScreen, hScreenDC)  
 Form1.WindowState = vbMaximized 'распахиваем окно на полный экран  
End Sub  

Но только для формы нужно установить свойство AutoRedraw=True.

В начало В начало

Совет 429. Как открыть ниспадающее меню программным образом

Как известно, VB 6 включает возможность задания Style=5 (tbrDropDown) для объекта Button элемента управления Toolbar. В этом случае можно добавить кнопке несколько объектов ButtonMenu. Но открыть меню можно только с помощью щелчка стрелки. То есть нельзя выполнить такую операцию из программного кода. Эта задача может быть решена с помощью следующего кода:

Private Type POINTAPI  
  x As Long  
  y As Long  
End Type  
Private Declare Function GetCursorPos Lib "user32" _  
  (lpPoint as POINTAPI) As Long  
Private Declare Function ClientToScreen Lib "user32" _  
  (ByVal hWnd As Long, _  
   lpPoint as POINTAPI) As Long  
Private Declare Function SetCursorPos Lib "user32" _  
  (ByVal x As Long, ByVal y As Long) As Long  
Private Declare Function ShowCursor Lib "user32" _  
  (ByVal bShow As Long) As Long  
Private Declare Sub mouse_event Lib "user32" _  
  (ByVal dwFlags As Long, ByVal dx As Long, _  
   ByVal dy As Long, ByVal cButtons As Long, _  
   ByVal dwExtraInfo As Long)  
Private Sub ShowPopUpMenu _  
  (TB As Toolbar, IndexOfButton%)  
  ' раскрываем меню  
  CONST MOUSEEVENTF_LEFTDOWN = &H2  
  Const MOUSEEVENTF_LEFTDOWN = &H2  
  Const MOUSEEVENTF_LEFTUP = &H4  
  Dim Pt As POINTAPI, oldPt As POINTAPI  
  With TB.Buttons(IndexOfButton)  
    If Not (.Style = tbrDropdown Then Exit Sub  
    ' режим разрешен  
    Call GetCursorPos(oldPt) ' запоминаем позицию курсора  
    Call ClientToScreen(TB.hWnd, Pt)  
    Call ShowCursor(False)  
    ' устанавливаем курсор на стрелку  
    Call SetCursorPos(Pt.x + ((.Left + .Width) / _  
       Screen.TwipsPerPixelX) - 1, _  
       Pt.y + ((.Top + .Height)\ 2 /_  
       Screen.TwipsPerPixelY))  
  End With  
  ' имитируем щелчок мышью  
  Call mouse_event(MOUSEEVENTF_LEFTDOWN, _  
     0, 0, 0, 0)        
  Call mouse_event(MOUSEEVENTF_LEFTUP, _  
     0, 0, 0, 0)        
  ' восстанавливаем позицию курсора мыши  
  Call SetCursor(oldPt.x, oldPt.y)  
  Call ShowCursor (True)  
End Sub  

Используя эту подпрограмму, можно, например, открыть меню, когда пользователь щелкнет саму кнопку:

Sub ToolBar1_ButtonClick _  
   (ByVal Button As MSComctllib.Button)  
  Call ShowPopUpMenu (Toolbar1.Button.Index)  
End Sub  
В начало В начало

Совет 430. Формирование кода цвета для HTML

Ета функция преобразует числовое значение цвета в строковую переменную для использования в HTML:

Public Function HtmlHexColor _  
  (ByVal ColorValue As Long) As String  
  Dim r As Byte  
  Dim g As Byte  
  Dim b As Byte  
  ' преобразование цвета (если это нужно)  
  Call OleTranslateColor _  
    (ColorValue, 0&, ColorValue)  
  r = ColorValue Mod &H10  
  g = (ColorValue \ &h100) Mod &H100   
  b = (ColorValue \ &h10000) Mod &H100  
  HtmlHexColor = "#" & _  
    Right$("0" & Hex$(r),2) & _  
    Right$("0" & Hex$(g),2) & _  
    Right$("0" & Hex$(b),2)  
 End Function  
В начало В начало

Совет 431. Модернизация объекта Err

Как это ни странно, но вы можете расширить функциональность встроенного объекта Err. Создайте класс с именем Cerror и включите в него такую процедуру свойства:

Public Property Get Number() As Long  
  Number = VBA.Err.Number  
End Property  
Далее создайте BAS-модуль со следующим кодом:  
Public Function Err() As Cerror  
  Static oErr As Cerror
   
  If oErr Is Nothing Then  
    Set oErr = New Cerror  
  End If  
  Set Err = oErr  
End Function  

Теперь вы можете обращаться к созданному объекту Cеrror для которого можно создать любой набор свойств и методов.

КомпьютерПресс 3'2002

1999 1 2 3 4 5 6 7 8 9 10 11 12
2000 1 2 3 4 5 6 7 8 9 10 11 12
2001 1 2 3 4 5 6 7 8 9 10 11 12
2002 1 2 3 4 5 6 7 8 9 10 11 12
2003 1 2 3 4 5 6 7 8 9 10 11 12
2004 1 2 3 4 5 6 7 8 9 10 11 12
2005 1 2 3 4 5 6 7 8 9 10 11 12
2006 1 2 3 4 5 6 7 8 9 10 11 12
2007 1 2 3 4 5 6 7 8 9 10 11 12
2008 1 2 3 4 5 6 7 8 9 10 11 12
2009 1 2 3 4 5 6 7 8 9 10 11 12
2010 1 2 3 4 5 6 7 8 9 10 11 12
2011 1 2 3 4 5 6 7 8 9 10 11 12
2012 1 2 3 4 5 6 7 8 9 10 11 12
2013 1 2 3 4 5 6 7 8 9 10 11 12
Популярные статьи
КомпьютерПресс использует