Леонтьев Б.К. Я изучаю Microsoft Office Visio 2003 (PDF). Удк 004. 738. 5 Ббк 32. 973. 26 018. 2
Скачать 0.88 Mb.
|
Check1 — массив чекбоксов, iDesired — переменная, хранящая двоичное представление состояния чекбоксов. Условная компиляция кода Вы можете объявлять процедуры Windows API для 16 или 32 раз рядных операционных систем при использовании Conditional Compila tion из Visual Basic 6.3: Использование редактора Visual Basic 289 290 Использование редактора Visual Basic #If Win#32 then ' если 32 разрядная ОС Declare SomeApi.... #Else ' если запущена 16 разрядная ОС Declare SomeApi #End IF Это же может работать не только с функциями Windows API, но и с вашими собственными функциями: #If Win32 Then Dim lRc& lRc& = ReturnSomeNumber(35000) #Else Dim lRc% lRc% = ReturnSomeNumber(30000) #End If #If Win32 Then Private Function ReturnSomeNumber_ (lVar&) As Long ReturnSomeNumber = 399999 #Else Private Function ReturnSomeNumber_ (lVar%) As Integer ReturnSomeNumber = 30000 #End If End Function Уменьшить мерцание во время загрузки формы Во время загрузки формы, следующий код поможет уменьшить мерцание и мелькание GUI при помощи функций API: 'Declarations Section #If Win32 Then Declare Function LockWindowUpdate _ Lib "user32" _ (ByVal hwndLock As Long) As Long #Else Declare Function LockWindowUpdate _ Lib "User" _ (ByVal hwndLock As Integer) _ As Integer #End If Public Sub LoadSomeForm() ' Во время загрузки формы запрещает обновление состояния окна ' чтобы избавиться от мерцания. ' запрещает обновление GUI LockWindowUpdate frmTest.hWnd ' показывает форму frmTest.Show ' здесь код, относящийся к загрузка формы и т.п. ' Никогда не забывайте разрешить обратно обновление окна LockWindowUpdate 0 End Sub Спрятать указатель на текущую запись в DBGride Для того, чтобы указатель записи на DBGride не скакал при пере мещении между записями (строками grida), используйте функцию API LockWindowUpdate(gridname.hwnd) перед началом движения по gridу, и LockWindowUpdate(0) после окончания перемещений: 'Declarations Section #If Win32 Then Declare Function LockWindowUpdate _ Lib "user32" _ (ByVal hwndLock As Long) As Long #Else Declare Function LockWindowUpdate _ Lib "User" _ (ByVal hwndLock As Integer) _ As Integer #End If Private Sub cmdHideSelector_Click() LockWindowUpdate DBGrid1.hWnd End Sub Private Sub cmdShowSelector_Click() LockWindowUpdate 0 End Sub Как узнать разделители даты и времени без функции API Вот простой алгоритм, как узнать разделители даты, времени и де сятичной точки в Windows, не залезая в Locale Settings или функции API. DateDelimiter = Mid$(Format(Date, _ "General Date"), 3, 1) TimeDelimiter = Mid$(Format(0.5, _ "Long Time"), 3, 1) DecimalDelimiter = Mid$(Format(1.1, _ "General Number"), 2, 1) Использование редактора Visual Basic 291 292 Использование редактора Visual Basic Дублирование строк кода без синтаксических ошибок Часто приходится переписывать сходный по смыслу код с неболь шими изменениями в каждой строке; для облегчения проблемы можно сделать шаблон того, что надо копировать, быстро вставлять копию в нужное место, и делать добавления. Однако часто шаблонный текст вы зывает ошибки со стороны Visual Basic 6.3 редактора. Одолеть эту про блему можно, закомментировав шаблон перед использованием. Когда вы закончите редактирование вставленного фрагмента, раскомменти руйте его и он готов. Это особенно просто под Visual Basic 6.3, в котором есть команда Block Uncomment. Ниже приведен пример добавления чле на в коллекцию. While Not mRS.EOF oObject.FName = mRS!FName oObject.LName = mRS!LName oObject.Phone = mRS!Phone cCollection.Add oObject, oObject.FName Wend В случае, если же у вашего объекта 20 или 30 свойств, быстрее бу дет создать шаблон: ' oObject. = mRS! Скопируйте его, вставьте 20 или 30 раз, вернитесь к началу и впе чатайте имена свойств и полей, и уберите символ комментария. Символ комментария позволяет вам свободно бегать по всему фрагменту, не за ботясь о синтаксических ошибках. Ярлык для загрузки последнего рабочего проекта в Visual Basic 6.3 Часто вы стартуете Visual Basic 6.3 и возобновляете работу с по следним проектом, но вам не хочется загромождать desktop иконками для текущих работ. В качестве решения предлагается программа, кото рую нужно скомпилировать и запустить на вашем desktopе. Эту програм му можно применить и к другим, использующим INI файлы. Option Explicit Declare Function GetPrivateProfile_ String Lib "kernel32" _ Alias "GetPrivateProfileStringA" _ (ByVal lpApplicationName As _ String, ByVal lpKeyName As Any, _ ByVal lpDefault As String, _ ByVal lpReturnedString As _ String, ByVal nSize As Long, _ ByVal lpFileName As String) _ As Long Public Sub Main() Dim temp As String, rVal$, tmp _ As Long rVal$ = String$(256, 0) tmp = GetPrivateProfileString_ ("Visual Basic", _ "vb32location", "", rVal$, _ ByVal Len(rVal$) — 1, _ "c:\windows\vb.ini") temp = Left$(rVal$, tmp) rVal$ = String$(256, 0) tmp = GetPrivateProfileString_ ("Visual Basic", "RecentFile1", _ "", rVal$, ByVal Len(rVal$) _ 1, "c:\windows\vb.ini") temp = temp & " """ & Left$(rVal$, _ tmp) & """" Shell temp, 1 End End Sub Создание временных файлов При программировании баз данных можно создавать временные файлы для, к примеру, вывода результата инструкции SQL или из вре менной базы данных, чтобы более эффективно работать с записями. Функция FileAux возвращает имя временного файла. В случае, если надо создать несколько временных файлов одновременно, сохраните их име на в заранее определенных переменных: Function FileAux(Ext As String) _ As String Dim i As Long, X As String If InStr(Ext, ".") = 0 Then Ext = "." + Ext End If ' Ищем уже имеющиеся файлы на винте i = 0 Do X = "Aux" + Format$(i, "0000") _ + Ext If FileExists(X) Then Использование редактора Visual Basic 293 294 Использование редактора Visual Basic i = i + 1 Else Exit Do End If Loop FileAux = X End Function Эта функция обращается к функции FileExists: Function FileExist(filename As String) _ As Boolean FileExist = Dir$(filename) <> "" End Function А вот пример использования: Sub Test() Dim File1 As String, File2 As _ String, File3 As String Dim DB1 As database, DB2 As DataBase Dim FileNum As Integer File1 = FileAux("MDB") Set DB1 = CreateDataBase(File1) File2 = FileAux("MDB") Set DB2 = CreateDataBase(File2) File3 = FileAux("TXT") FileNum = FreeFile Open File3 For OutPut As FileNum ' Ваш код ' ... Close FileNum End Sub File1, File2 и File3 должны быть Aux0001.MDB, Aux0002.MDB и Aux0001.TXT соответственно. Центрировать форму с учетом TaskBar Для центрирования формы вам надо лишь вызвать API процедуру, и завести две константы. Это решение основано на том факте, что GetSystemMetrics возвращает истинное значение параметров экрана, ко торый может быть на самом деле занят таскбаром и Microsoft Office short cut barом: Public Const SM_CXFULLSCREEN = 16 Public Const SM_CYFULLSCREEN = 17 #If Win32 then Declare Function GetSystemMetrics _ Lib "user32" _ (ByVal nIndex As Long) As Long #Else Declare Function GetSystemMetrics _ Lib "User" _ (ByVal nIndex As Integer) _ As Integer #End If Public Sub CenterForm(frm As Form) frm.Left = Screen.TwipsPerPixelX * _ GetSystemMetrics_ (SM_CXFULLSCREEN) / 2 _ frm.Width / 2 frm.Top = Screen.TwipsPerPixelY * _ GetSystemMetrics_ (SM_CYFULLSCREEN) / 2 _ frm.Height / 2 End Sub Очистка строки от ненужных символов Иногда бывает полезно иметь функцию, которая очищает строку от нежелательных символов. Эта маленькая функция принимает в каче стве параметров строку для очистки и символ, от которого ее надо очис тить: Function StringCleaner(s As String, _ Search As String) As String Dim i As Integer, res As String res = s Do While InStr(res, Search) i = InStr(res, Search) res = Left(res, i — 1) & _ Mid(res, i + 1) Loop StringCleaner = res End Function Добавление строки в TEXT BOX Используйте данный код, чтобы заставить скроллер TextBox авто матически передвинуться, когда вы добавляете новый текст: ' Переход к концу текста MyTextBox.SelStart = Len(MyTextBox.Text) Использование редактора Visual Basic 295 296 Использование редактора Visual Basic ' Новый текст будет стоять здесь MyTextBox.SelText = NewText$ Проверка аргументов в функции VAL При использовании функции Val, Visual Basic 6.3 капризничает, порождая ошибку несоответствия типов. Например, Val(«25%») пра вильно возвращает 25, тогда как Val(«2.5%») неправильно интерпретиру ет входной параметр и возвращает ошибку несоответствия типов. Это случается только тогда, когда в строке присутствует десятич ная точка и символ «%» или «&». Для того, чтобы исправить это, уберите эти символы из строки перед ее передачей в Val. Ярлыки для Интернет Visual Basic 6.3 умеет создавать web форму, но она работает только с Microsoft Internet Explorer и вам приходится таскать за собой SHD OCVW.DLL при распространении программы. В случае, если вы исполь зуете функцию ShellExecute для запуска файла Internet Shortcut, то Windows запускает дефолтный браузер и переходит на указанный URL. Этот метод работает как Microsoft так и с Netscape браузерами, если они правильно прописаны в регистре, и вам не нужно перетаскивать никаких DLL при распространении программы. Private Declare Function ShellExecute _ Lib "shell32.dll" Alias _ "ShellExecuteA" _ (ByVal hwnd As Long, _ ByVal lpOperation As String, _ ByVal lpFile As String, _ ByVal lpParameters As String, _ ByVal lpDirectory As String, _ ByVal nShowCmd As Long) As Long Private Const SW_SHOWNORMAL = 1 ' frm : ShellExecute использует обработчик окна. ' Вы можете использовать обработчик главного окна проги ' sUrl : это имя и путь к файлу .url (файл Internet shortcut) ' указывающий на Вашу страницу , напр. ' c:\MyWebPage.url использует Internet Explorer ' для создания файла ярлыка Public Sub GoToMyWebPage(frm as Form, _ sUrl as string) Dim lRet as Long lRet = ShellExecute(frm.hwnd, _ "open", sUrl, vbNull, _ vbNullString, SW_SHOWNORMAL) If lRet <= 32 Then ' случилась ошибка. Некоторые из ошибок, ' возвращаемых ShellExecute: ' ERROR_FILE_NOT_FOUND = 2& ' ERROR_PATH_NOT_FOUND = 3& ' ERROR_BAD_FORMAT = 11& ' SE_ERR_NOASSOC = 31 ' SE_ERR_OOM = 8 Else ' если браузер запущен! End If End Sub Просмотр содержания HELP файла Многие программисты любят добавлять к своим приложениям и хелп файлы. Как открыть содержание help файла Windows из вашей программы? Вот пример кода с использованием Win32 API функции. ' Объявление Const HELP_CONTENTS = &H3& ' Функции Вывода содержимого Declare Function WinHelp Lib "user32" _ Alias "WinHelpA" _ (ByVal hwnd As Long, _ ByVal lpHelpFile As String, _ ByVal wCommand As Long, _ ByVal dwData As Long) As Long ' Код Sub OpenHelpFile(HelpFileName As String) ' HelpFileName — путь к хелп файлу. WinHelp hwnd, HelpFileName, _ HELP_CONTENTS, 0 End Sub Быстрый поиск в базе данных В Visual Basic 6.3 нет встроенной процедуры типа DLookUp из Аccess. Вы можете использовать нижеприведенный код для получения Name объекта по его ID: Public Function MyDLookUp(Column As _ String, TableName As String, _ Condition As String) As Variant Dim Rec As Recordset On Error GoTo MyDlookUp_Err ' gCurBase — глобальная переменая, указывающая на текущкю БД Использование редактора Visual Basic 297 298 Использование редактора Visual Basic Set Rec = gCurBase.OpenRecordset_ ("Select * From " & TableName) Rec.FindFirst Condition If Not Rec.NoMatch Then ' возвращает искомое поле, если найдено MyDLookUp = Rec(Column) Exit Function End If ' возврат, если не найдено, или произошла другая ошибка MyDlookUp_Err: MyDLookUp = 1 End Function Легкое отслеживание положения фокуса Lost_Focus и Got_Focus events часто используются для проверки правильности ввода текста. Вы можете использовать нижеприведенный код для отслеживания фокуса на форме, не программируя каждый кон трол отдельно. Поместите timer control на форму, установите Interval property = 100 и Enabled = True. Name the control tmrFocusTracking. Timer event должен содержать следующий код: Private Sub tmrFocusTracking_Timer() Dim strControlName As String Dim strActive As String strControlName = _ Me.ActiveControl.Name Do strActive = Me.ActiveControl.Name If strControlName <> strActive _ Then Print strControlName & _ " — Lost Focus", _ strActive & " — Got Focus" strControlName = strActive End If DoEvents Loop End Sub To implement universal highlighting, replace the Print statement with this code: Me.Controls(strActive).SelStart = 0 Me.Controls(strActive).SelLength = _ Len(Me.Controls(strActive)) Для проверки (validation) правильности текста вместо Print state ment используйте вызов процедуры проверки. К моменту, когда случается команда Print, strActive равен контро лу, имеющему фокус, и strControlName содержит имя контрола, который потерял фокус. Не размещайте эту процедуру где либо кроме таймера. Незакрывающаяся форма В случае, если выставить свойство ControlBox на форме в False, то кнопки Minimize и Maximize тоже исчезнут. Предположим, что вы хотите тем не менее давать возможность юзеру использовать кнопки Minimize и Maximize, но при этом чтобы он не мог закрыть форму кнопкой с крести ком. Добавьте следующий код в событие Query_Unload: ' если у Вас VB3, раскомментируйте следующую строку ' Const vbFormControlMenu = 0 Private Sub Form_QueryUnload(Cancel As _ Integer, UnloadMode As Integer) If UnloadMode = vbFormControl_ Menu Then Cancel = True End If End Sub Как просто отформатировать и округлить число Пример округления с заданной точностью: n = 12.345 Format(n, "0.00\0") ' возвращает "12.350" Format(n, "0.\0\0") ' возвращает "12.00" Format(0.55, "#.0\0") ' возвращает ".60" Будьте осторожны, здесь вам не С! VB программеры, привыкшие к С, могут быть введены в заблужде ние следующей особенностью VB. Рассмотрим код: Dim x As Integer Dim y As Integer Dim z As Integer x = 10 y = 20 Использование редактора Visual Basic 299 300 Использование редактора Visual Basic z = 0 ' пусть функция max возвращает большее из двух чисел if (z = max(x, y)) > 0 then Msgbox CStr(z) Else Msgbox "How Come?" End if Вы ожидаете, что высветится 20, как должно бы было произойти в С? Однако, Visual Basic 6.3 сравнит z с RHS (right hand side, правой сто роной), даже перед присвоением, независимо от скобок. Будьте внима тельны. Использовать BACKQUOTES вместо апострофов Часто при использовании Transact SQL надо перехватывать ком ментарии пользователя из текстбокса и пересылать их в базу данных. Од нако, если юзер нажимает апостроф в текстбоксе, происходит ошибка времени выполнения, поскольку SQL Server использует апостроф как признак конца строки. Для того, чтобы обойти эту проблему, перехвати те ввод юзера в событии KeyPress и замените апостроф на вот такую ка вычку «'»(ASCII(145)): Private Sub Text1_Keypress_ (KeyAscii as Integer) If KeyAscii = 39 Then KeyAscii = 145 End If End Sub Также можно заменить все одинарные кавычки на «'» перед от сылкой в SQL Server. Распространение новых версий программы по сети Довольно трудно своевременно уследить за распространением каждой новой версии программы на всех машинах, поэтому необходимо использовать автоинкрементирующуюся нумерацию версий для провер ки, требуется ли апгрейд программы на конкретной машине. При ком пиляции программы установите автоинкремент версий в On. Сохраните ваши setup/upgrade файлы на сетевом диске (настоятельно рекомендуем использовать UNC пути ( \\имя_машины\имя_диска) нежели просто имена дисков), и положите INI файл программы, в котором указан но мер новейшей версии. Затем вставьте следующий код в программу, собы тие Form_Load: Open IniFile$ For Input As #1 Line Input #1, sUpgradeVersion$ Close #1 If sUpgradeVersion > (Format(App.Major, "00") & "." & _ Format(App.Minor, "00") & "." & _ Format(App.Revision, "0000")) Then ' запуск апгрейда с сетевого диска End End If В случае, если версия в INI файле выше, чем версия, записанная в .exe, то программа автоматом запустит программу апгрейда по сети и за кончит свое выполнение, то есть все нужные файлы смогут быть замене ны. Это особенно полезно, когда вы только начинаете писать программу, то есть апгрейды появляются чуть ли не раз в несколько дней. Закрыть окно программы, как это делает Windows XP Разместите этот код в declaration section модуля: Public Sub Win95Shrivel(xForm As Form) ' минимизирует окно xForm.WindowState = 1 End Sub Вызывайте ее из процедуры Unload формы Private Sub Form_Unload(Cancel As _ Integer) Win95Shrivel Me End Sub Каждый раз при unloade формы она сначала быстро сворачивает ся к таскбару, а затем исчезает. Excel VBA: Приёмы программирования Как определить последнюю запись в таблице Excel? Необходимо найти последнюю запись в электронной таблице. Это можно было бы организовать, к примеру, функцией |