Леонтьев Б.К. Я изучаю Microsoft Office Visio 2003 (PDF). Удк 004. 738. 5 Ббк 32. 973. 26 018. 2
Скачать 0.88 Mb.
|
Application.Speci alCells(xlLastCell). Как из макроса Excel программно создать таблицу Access? Вот фрагмент кода, который создаёт таблицу BalanceShifr базе данных MS Access: Использование редактора Visual Basic 301 302 Использование редактора Visual Basic ' Function CreateTable ' Create temporary table "BalanceShifr" into temporary database Public Function CreateTable(ByVal dbTemp As Database) As Boolean Dim tdfTemр As TableDef Dim idx As Index Dim fld As Field On Error GoTo errhandle CreateTable = True ' CREATE TABLE "BalanceShifr" Set tdfTemp = dbTemp.CreateTableDef("BalanceShifr") Set fld = tdfTemp.CreateField("ConditionId", dbLong) fld.Required = True tdfTemp.Fields.Append fld Set fld = tdfTemp.CreateField("Account", dbText, 4) tdfTemp.Fields.Append fld Set fld = tdfTemp.CreateField("SubAcc", dbText, 4) tdfTemp.Fields.Append fld Set fld = tdfTemp.CreateField("Shifr", dbLong) tdfTemp.Fields.Append fld Set fld = tdfTemp.CreateField("Date", dbDate) fld.Required = True tdfTemp.Fields.Append fld Set fld = tdfTemp.CreateField("SaldoDeb", dbCurrency) tdfTemp.Fields.Append fld Set fld = tdfTemp.CreateField("SaldoKr", dbCurrency) tdfTemp.Fields.Append fld dbTemp.TableDefs.Append tdfTemp ' CREATE INDEX "BalanceShifr" Set tdfTemp = dbTemp.TableDefs("BalanceShifr") Set idx = tdfTemp.CreateIndex("ForeignKey") Set fld = idx.CreateField("ConditionId") idx.Fields.Append fld tdfTemp.Indexes.Append idx Exit Function errHandle: MsgBox "Table creating error!", vbExclamation, "Error" CreateTable = False End Function Как удалить рабочие листы листов в зависимости от даты? Вот код функции на Excel VBA, который решает данную проблему: ' Function DelSheetByDate ' Удаляет рабочий лист sSheetName в активной рабочей книге, ' если дата dDelDate уже наступила ' В случае успеха возвращает True, иначе — False Public Function DelSheetByDate(sSheetName As String, _ dDelDate As Date) As Boolean On Error GoTo errHandle DelSheetByDate = False ' Проверка даты If dDelDate <= Date Then ' Не выводить подтверждение на удаление Application.DisplayAlerts = False ActiveWorkbook.Worksheets(sSheetName).Delete DelSheetByDate = True Application.DisplayAlerts = True End If Exit Function errHandle: MsgBox Err.Description, vbCritical, "Ошибка ?" & Err.Number End Function Как подавить доступ по «горячим» клавишам, имеется ввиду предопределенные в Excel клавиши типа Ctrl O и т.д.? Вот небольшой исходник на Excel VB, который решает такую про блему. Public Sub Auto_Open() ' Overrride standard accelerators With Application .OnKey "^o", "Dummy" .OnKey "^s", "NewAction" .OnKey "^р", "" ' Kill hotkey ! End With End Sub ' Public Sub Dummy() MsgBox "This hotkey redefined!" End Sub ' Public Sub NewAction() SendKeys "^n" ' Press Использование редактора Visual Basic 303 304 Использование редактора Visual Basic ' instead of End Sub Как сделать к «самонарисованным» кнопочкам на Toolbar'е подсказки? Сделать можно вот как: ' Cоздаем тулбар Рublic Sub InitToolBar() Dim cmdbarSM As CommandBar Dim ctlNewBtn As CommandBarButton Set cmdbarSM = CommandBars.Add(Name:="MyToolBar", Position:=msoBarFloating, _ temporary:=True) With cmdbarSM ' 1) Добавляем кнопку Set ctlNewBtn = .Controls.Add(Type:=msoControlButton) With ctlNewBtn . FaceId = 26 .OnAction = "OnButton1_Click" .TooltipText = "My tooltip message!" End With ' 2) Добавляем ещё кнопку Set ctlNewBtn = .Controls.Add(Type:=msoControlButton) With ctlNewBtn .FaceId = 44 .OnAction = "OnButton2_Click" .TooltipText = "Another tooltip message!" End With .Visible = True End With End Sub Как в макросе узнать и использовать текущее положение курсора (не мышиного, естественно)? Очень просто! ActiveCell.Row и ActiveCell.Column покажут координаты активной ячейки. Как узнать есть ли хоть один Notes (комментарий) в рабочем листе, кроме как перебором по всем ячейкам? В Excel эта проблема может быть решена вот как: ' Function IsCommentsPresent ' Возвращает TRUE, если на активном рабочем листе имеется хотя бы ' одна ячейка с комментарием, иначе возвращает FALSE ' Public Function IsCommentsPresent() As Boolean IsCommentsPresent = ( ActiveSheet.Comments.Count <> 0 ) End Function Как сделать свой собственный Toolbar с tooltip'ами на кнопках в Excel? Вот фрагмент кода для Excel, который создаёт toolbar с одной кнопкой с пользовательским tooltiр'ом. Нажатие кнопки приводит к вы полнению макроса NothingToDo(). ' This example creates a new toolbar, adds the Camera button ' (button index number 228) to it, and then displays the new ' toolbar. ' Public Sub CreateMyToolBar() Dim myNewToolbar As Toolbar On Error GoTo errHandle: Set myNewToolbar = Toolbars.Add(Name:="My New Toolbar") With myNewToolbar .ToolbarButtons.Add Button:=228, StatusBar:="Statusbar help string" .Visible = True With .ToolbarButtons(1) .OnAction = "NothingToDo" .Name = "My custom tooltiр text!" End With End With Exit Sub errНandle: MsgBox "Error number " & Err & ": " & Error(Err) End Sub ' ' Toolbar button on action code ' Рublic Sub NothingToDo() MsgBox "Nothing to do!", vbInformation, "Macro running" End Sub Как запустить Excel, чтобы оказаться на ячейке содержимое которой известно заранее? Вот как можно решить эту задачу: ' Sub GotoFixedCell: ' Делает активной ячейку, содержащую значение vVariant на ' рабочем листе sSheetName в активной рабочей книге. Использование редактора Visual Basic 305 306 Использование редактора Visual Basic ' ' Note: Содержимое ячеек интерпретируется как 'значение'! ' Public Sub GotoFixedCell(vValue As Variant, sSheetName As String) Dim c As Range, cStart As Range, cForFind As Range Dim i As Integer On Error GoTo errhandle: Set cForFind = Worksheets(sSheetName).Cells ' Диапазон поиска With cForFind Set c = .Find(What:=vValue, After:=ActiveCell, LookIn:=xlValues, _ LookAt:= xlРart, SearchOrder:=xlByRows,_ SearchDirection:=xlNext, MatchCase:=False) Set cStart = c While Not c Is Nothing Set c = .FindNext(c) If c.Address = cStart.Address Then c.Select Exit Sub End If Wend End With Exit Sub errНandle: MsgBox Err.Descriрtion, vbExclamation, "Error #" & Err.Number End Sub Хочy через Excel VBA задать имя листу, который будет вставлен. Но у команды Sheets.Add нет такого параметра! Как бороться? Очень просто... ' ' Sub CreateSheet ' Вставляет активную рабочую книгу в рабочий лист с именем ' sSName. ' Note: В случае, если параметр bVisible имеет значение False, ' этот лист становится скрытым. ' Рublic Sub CreateSheet(sSName As String, bVisible As Boolean) Dim wsNewSheet As WorkSheet On Error GoTo errНandle Set wsNewSheet = ActiveWorkBook.Worksheets.Add With wsNewSheet .Name = sSName .Visible = bVisible End With Exit Sub errНandle: MsgBox Err.Descriрtion, vbExclamation, "Error #" & Err.Number End Sub Как проверить существует ли лист? Можно поступить вот как: ' Function IsWorkSheetExist ' Проверяет, имеется ли в активной рабочей книге лист ' с именем sSName. ' В случае успеха возвращает True, иначе — False ' Рublic Function IsWorkSheetExist(sSName As String) As Boolean Dim c As Object On Error GoTo errНandle: Set c = sheets(sName) ' Альтернативный вариант : Worksheets(sSName).Cells(1, 1) = Worksheets(sSName).Cells(1, 1) IsWorkSheetExist = True Exit Function errНandle: IsWorkSheetExist = False End Function Как обратиться к ячейке по ее имени? Как обратиться к ячейки по ее имени? То есть есть Лист1 и в нем ячейки с именем Дебет и Кредит. Необходимо подсчитать Дебет Кредит средствами Excel VBA. При использовании Range(Дебет) Range(Кредит) выдается ошибка, что не описаны переменные. Нужно разыменовать ячейку из кода Excel VBA. Вот фрагмент ко да, который решает такую задачу: ' Function ValueOfNamedCell ' Возвращает значение ячейки с именем sCellName. ' в активной рабочей книге. ' Note: В случае, если ячейка с именем sCellName не существует — ' функцией возвращается ' значение Emрty. ' Рublic Function ValueOfNamedCell(sCellName As String) As Variant On Error GoTo errНandle ValueOfNamedCell = ActiveWorkbook.Names(sCellName).RefersToRange.Value Exit Function Использование редактора Visual Basic 307 308 Использование редактора Visual Basic errНandle: ValueOfNamedCell = Emрty End Function Можно ли из программы на Visual Basic создать рабочую книгу Excel? Да, можно. Пример того, как из Visual Basic через OLE запустить Excel, и создать рабочую книгу: ' CreateXlBook ' Вызывает MS Excel, создает рабочую книгу с именем sWbName с ' одним единственным рабочим листом. ' Рабочая книга будет сохранена в каталоге ' sDirName. В случае успеха возвращает True, ' в противном случае — False. ' Public Function CreateXlBook(sWbName As String, sDirName) As Boolean ' MS Excel hidden instance Dim objXLApp As Object Dim objWbNewBook As Object CreateXlBook = False Set objXLApp = CreateObject("Excel.Application") If objXLApp Is Nothing Then Exit Function ' В новой рабочей книге создавать только один рабочий лист objXLApp.SheetsInNewWorkbook = 1 Set objWbNewBook = objXLApp.Workbooks.Add If objWbNewBook Is Nothing Then Exit Function ' Сохраняем книгу If vbNullString = Dir(sDirName, vbDirectory) Then Exit Function objWbNewBook.SaveAs (sDirName + "\" + sWbName + ".xls") CreateXlBook = True ' Освобождение памяти Set objWbNewBook = Nothing objXLApp.Quit Set objXLApp = Nothing CreateXlBook = True End Function Типы переменных Всегда используйте Integer или Long тип переменных, где это воз можно. Процессор обрабатывает эти переменные за один такт. Используйте Singl вместо Double, они короче и быстрее. Не используйте Variant, если это возможно. Обязательно добавьте в General каждого модуля Option Explicit или, как альтернативу — DefLong A Z. Локальные переменные типа Static в 2–3 раза медленнее, чем обычные локальные переменные. Также они медленнее, чем перемен ные уровня формы. В то же время переменные формы несколько быстрее переменных модуля. Явные и неявные преобразования Остерегайтесь использовать функции Int и Val — они всегда воз вращают вещественное значение с плавающей точкой. В случае, если вы используете Long или Integer, применяйте CInt или CLng. result% = Val(Text1.Text) result% = Int(Text1.Text) result% = CInt(Text1.Text) result% = Text1.Text Каждое утверждение в этом коде немного быстрее, чем предыду щее; последнее — приблизительно на 30 процентов быстрее чем первое. Используйте «\» вместо «/» при делении целых. Избегайте лишних неявных преобразований, так как оператор «/» возвращает значение Single. Имейте в виду, что оператор «/» возвращает значение Double, если по крайней мере один из элементов имеет тип Double. Бейсик хранит константы в наиболее простой форме: скажем, кон станта, несущая единицу, хранится как целое, если вы предполагаете ис пользовать ее для действий с вещественными числами, объявите ее явно: Const ONE As Double = 1 Математика Самые быстрые функции те, результаты работы которых вы може те оценивать заранее. Например, сохранение факториалов всех чисел в диапазоне от одного до 100 в массив один раз в начале программы — на много быстрее, чем предположительные тысячи вызовов функции в те чение жизни приложения. Используйте оператор And вместо Mod, когда делитель — число в формате 2 ^ N. Например, вы можете использовать два метода извлечь самый младший байт в Целом числе: lowByte% = value% Mod 256 lowByte% = value% And 255 Второй немного быстрее. Используйте Boolean в операторах сравнения Использование редактора Visual Basic 309 310 Использование редактора Visual Basic Например: If x <> 0 Or y <> 0 Then ... Работает так же как это: If x Or y Then ... А это: If x = 0 And y = 0 Then ... Так же как это : If (x Or y) = 0 Then ... Даже оператор XOR может сэкономить немного времени: If (x = 0 And y = 0) Or (x <> 0 And y <> 0) Then ... А побыстрее так: If (x = 0) Xor (y <> 0) Then .. Иногда вы можете заменить весь If...Else блок более простой опе рацией Boolean. Например, вы можете заменить этот код: If x > 0 Then y = 1 Else y = 0 на другой, хотя и весьма загадочный y = (x > 0) При этом вы обязательно должны добавить замечание, которое ясно объясняет, что ваш код делает, во избежании проблем сопровожде ния в дальнейшем. Ускорение массивов Чтение и запись элемента массива всегда медленнее, чем доступ к простой переменной. Следовательно, если вы должны использовать тот же самый элемент массива в цикле неоднократно, вы должны назначить временную переменную, содержащую этот элемент, и использовать именно ее. В циклах повышение производительности может достигать 80 процентов. По той же самой причине, обращение к элементам в матрице мед леннее чем доступ к элементам в моноразмерном массиве. Примите это во внимание при проектировании ваших алгоритмов. При частом поиске в массиве, содержание которого не меняется, часто имеет смысл подумать о сортировке. Сортировка обычно — мед ленное занятие, но сортировка с использованием Hash tables может уско рить процесс сортировки во много раз. В случае, если значения Integer элементов вашего массива не более 255, то имеет смысл преобразовать его в массив типа Byte. Это не ускорит код, но ресурсоемкость уменьшит, что актуально для старых машин. Копируйте блоки данных между массивами того же самого типа, используя функцию API CopyMemory вместо For...Next loop: Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, As Any, ByVal bytes As Long) ' copy a() into b() — b() is of same type and properly ' DIMensioned N is the number of items ' to copy CopyMemory b(0), a(0), n * Len(a(0)) Вы можете использовать эту функцию для сдвига элементов мас сива при простом добавлении элемента. При работе с матрицами используя вложенные циклы — внешний цикл должен выполнить итерации на столбцах, а внутренний — итера ции на строках (VB сохраняет матрицы один столбец после другого). Программа вызывает меньшее количество «листания». Никогда не используйте For Each на Variant массивах. Обычный For loop с Integer или Long индексом как минимум в двое быстрее. В случае, если вы абсолютно уверены, ваша программа Visual Basic 6.3 никогда не выдает Subscript out of range error, можете компилировать нэйтив код с опцией Remove Array Bounds Check. Это может ускорить программу с работой в массивах на 50 процентов или больше. Строковые операции Конкатенация — это медленная операция, если вы хотите заме нить 1 2 символа в строке — используйте функцию Mid$: Mid$(a$, 1, 1) = "A" Hе используйте такой код: a$ = "A & Mid$(a$, 2) Cтроковые переменные фиксированной длины часто медленнее, чем стандартные строковые переменные. Фактически, все строковые функции работают только со строками переменной длины. Следователь но, все строки фиксированной длины сначала должны быть преобразо ваны, прежде, чем обработаются. Это может замедлить ваш код раза в три или четыре. Используйте функции со знаком $, они возвращают вам строко вые значения, тогда как без доллара — Variant, что приводит к лишним преобразованиям. Использование ASCII кода чувствительно быстрее использования символа к примеру: If Left$(a$, 1) = " " Then ... ' If Asc(a$) = 32 Then ... Второе примерно на 40 процентов быстрее. Использование редактора Visual Basic 311 312 Использование редактора Visual Basic Используйте встроенные строковые константы вместо Chr$ (). Hапример, используйте vbTab вместо Chr$ (9), и vbCrLf вместо Chr$ (13) и Chr$ (10). Использование функции Len, чтобы проверить, содержит ли стро ка символы — приблизительно на 25 процентов быстрее, чем явное срав нение с пустой строкой: If Len(a$) = 0 Then ... Часто Visual Basic 6.3 программисты сравнивают строки, используя LCASE$ или UCASE$, чтобы преобразовать обе строки перед сравнени ем. Однако, быстрее прибегнуть к редко используемой функции StrComp: If StrComp(a$, b$, vbTextCompare) = 0 Then ' strings are equal End If Точно так же, когда вы должны искать подстроку в режиме без учета регистра, используйте функцию InStr с четвертым необязательным параметром: If Instr(1, a$, "vb", vbTextCompare) Then ... Функция InStr позволяет вам быстро проверять содержится ли одиночный символ в списке символов. Почти забытый оператор Like может часто сохранять много цик лов процессора, выполняя сложные строковые тесты в одной операции: If ID Like "[A Z]###" Then ... Здесь IP должен содержать букву и три цифры. Ускорение загрузки форм В случае, если позволяет память — не выгружайте часто использу емую форму — просто спрячьте ее, в следующий раз она появится мгно венно. Однако при этом событие |