Программирование на Visual Basic | Microsoft Access, Excel, Word

В этом разделе сайта находятся примеры из сборника программ "Архив файлов на Microsoft Access". В нем рассказывается о программировании форм, отчетов, таблиц и других объектов. Используйте этот архив для изучения работы с приложением Microsoft Office Access и программированием на Visual Basic for Application. Файлы исходников можно получить по этой ссылке: Купить и скачать

Экспорт в файлы всех объектов базы данных

Для экспорта всех объектов базы данных Microsoft Access (таблиц, запросов, форм, отчетов, макросов и модулей) в текстовые файлы можно использовать недокументированную команду SaveAsText.

Основной метод: SaveAsText
Эта команда позволяет сохранить структуру и код любого объекта в текстовый формат, что удобно для резервного копирования или систем контроля версий (Git). Написать конвертор преобразования VBA в другой язык и т.п.
Синтаксис:
Application.SaveAsText [ТипОбъекта], "[ИмяОбъекта]", "[ПутьКФайлу]"

Sub ExportAllObjects()
    Dim obj As AccessObject
    Dim path As String
    ' Путь к папке, где будут файлы (должна существовать)
    path = "C:\.\AccessExport\" 
    
    ' Экспорт форм
    For Each obj In CurrentProject.AllForms
        Application.SaveAsText acForm, obj.Name, path & obj.Name & ".txt"
    Next obj
    
    ' Экспорт отчетов
    For Each obj In CurrentProject.AllReports
        Application.SaveAsText acReport, obj.Name, path & obj.Name & ".txt"
    Next obj
    
    ' Экспорт модулей
    For Each obj In CurrentProject.AllModules
        Application.SaveAsText acModule, obj.Name, path & obj.Name & ".txt"
    Next obj
    
    ' Экспорт запросов (QueryDefs)
    Dim qdf As DAO.QueryDef
    For Each qdf In CurrentDb.QueryDefs
        Application.SaveAsText acQuery, qdf.Name, path & qdf.Name & ".txt"
    Next qdf
    
    MsgBox "Экспорт завершен"
End Sub

 

Кейс по программированию в Excel (VBA).

Для проверки ваших знаний  в Excel VBA Вы можете попробовать решить следующую тестовую задачу (кейс).  Она может потребоваться при приеме на работу как разработчика VBA и SQL Server.  Вот  её содержание.

  1. Необходимо создать таблицу на сервере MSSQL с 3 столбцами
  2. Реализовать загрузку данных на сервер из Excel (200 000 записей) через VBA или Python через UI. При реализации на Python можно использовать любой UI framework
  3. Сделать хранимую процедуру на MS SQL сервере для выгрузки данных за определенный период.
  4. Реализовать возможность указывать период от до (на форме VBA или значения в Excel, на выбранной UI framework форме) и результат хранимой процедуры из 3 пункта выгружать в новую книгу Excel. Так же реализовать форматирование отчета (закрепление шапки и формат столбцов)
  5. Отчет должен содержать столбцы: Год, Месяц, Артикул, средние продажи за год и месяц, доля продаж артикула за выбранный период
  6. Логика отчета с расчетом средних продаж и доли продаж должна быть реализована в хранимой процедуре
  7. Приложение. Файл data.xlsb с 200 тысяч записей.

Оценка работы

На первый взгляд задание простое, исходных данных не много, но есть нюансы. Их придется учитывать, а также то, что конкурсное задание могут решить правильно ваши конкуренты. Работодателю придется выбирать между вами и ими. Выход из этого такой. Надо уделить внимание качеству интерфейса, попытаться сделать его профессионально, например, с инсталляцией. Для решения задачи, я выбрал 3 этапа работы, которые и отобразил на форме Excel.

  1. Этап. Настройка интерфейса .
  2. Этап. Загрузка в базу данных из Excel.
  3. Этап. Создание отчёта за период

Ещё...

Microsoft Access. Примеры построения графиков в формах

03. Первая часть - при загрузке формы скрывается ее заголовок. Средствами Access можно убрать строку меню и границу, но тогда форма не имеет четко выраженной границы. Вторая часть - рисование полилиний разного цвета. При построении графиков для наглядности удобно представлять данные разными цветами в зависимости от уровня стандартные средства этого почему-то не поддерживают. Третья часть - пример использования регионов (..\02 Графика\la_graphics.accdb).

'константы для функции пересчета твипов
'значения 88 и 90 могут отличаться!
Public Const LOGPIXELSX = 88
Public Const LOGPIXELSY = 90

'константы для функции скрытия заголовка
Public Const STYLE = (-16)
Public Const CAPTION = HC00000
Public Const BORDER = H800000
Public Const NOMOVE = H2
Public Const NOSIZE = H1
Public Const NOZODER = H4
Public Const ShowWindow = H40
Public Const NOACTIVE = H10
Public Const FRAMECHANGED = H20

'вычисление коэффициента пересчета Twip в Pixel
Public Function TwipToPixel(i As Long) As Long
    Dim hDc As Long
    'получение идентификатора контеста устройства
    hDc = GetDC(0)
    Select Case i
    Case 1
    TwipToPixel = 1440 / GetDeviceCaps(hDc, LOGPIXELSX)
    Case 2
    TwipToPixel = 1440 / GetDeviceCaps(hDc, LOGPIXELSY)
    End Select
    'освобождение идентификатора
    ReleaseDC 0, hDc

End Function
'--
'GetDC возвращает контекст устройства (DC) окна
Public Declare Function GetDC Lib "user32" (ByVal hw As Long) As Long
'ReleaseDC освобождает ресурсы,которые были заняты
'при использовании GetDC для получения контекста устройства
Public Declare Function ReleaseDC Lib "user32" (ByVal hw As Long, ByVal hDc As Long) As Long

'получение характеристик дисплея
Public Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDc As Long, _
   ByVal iCapability As Long) As Long

'функция позволяет получить используемый стиль окна
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
 (ByVal hwnd As Long, ByVal nIndex As Long) As Long

'функция позволяет установить новый стиль окна
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
 (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
 
'функция отображает окно в указанном месте
Public Declare Function SetWindowPos Lib "user32.dll" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, _
ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal _
wFlags As Long) As Long

' Функция используется для поиска окна
 Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
  (ByVal hWndParent As Long, _
   ByVal hWndChildAfter As Long, _
   ByVal lpClassname As String, _
   ByVal lpWindowName As String) As Long

' Функция рисует ломаную с помощью выбранного "пера"
Public Declare Function Polygon Lib "gdi32" (ByVal hDc As Long, _
     lpPoint As POINTAPI, ByVal nCount As Long) As Long

' Функция рисует ломаную с помощью выбранного "пера"
Public Declare Function Polyline Lib "gdi32" (ByVal hDc As Long, _
     lpPoint As POINTAPI, _
     ByVal nCount As Long) As Long



' Структура координаты точки
Public Type POINTAPI
    x As Long
    Y As Long
End Type


'функция выбирает устройство для рисования
Public Declare Function SelectObject Lib "gdi32.dll" (ByVal hDc _
As Long, ByVal hObject As Long) As Long

'функция удаляет созданный объект для освобождения ресурсов
Public Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject _
As Long) As Long

'функция создает новое "перо"
Public Declare Function CreatePen Lib "gdi32.dll" (ByVal fnPenStyle _
As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long

'функция создает новую "кисть"
Public Declare Function CreateSolidBrush Lib "gdi32.dll" (ByVal _
crColor As Long) As Long

'функция создает прямоугольный регион
Public Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, _
ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long

'функция создает комбинацию из двух регионов
Public Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As _
Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal _
nCombineMode As Long) As Long

'функция отображает регион на окно
Public Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As _
Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

'функция позволяет получить размеры и положение окна
Public Declare Function GetWindowRect Lib "user32" (ByVal hwnd As _
Long, lpRect As Rect) As Long

'структура для данных, получаемых GetWindowRect
 Public Type Rect
  left As Long
  top As Long
  right As Long
  bottom As Long
End Type

'функция управляет "показом" окна
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As _
Long, ByVal nCmdShow As Long) As Long
'--



Public Function Скрыть_Заголовок(frm As Form, IndexX As Long, IndexY As Long)
    Dim OldStyle As Long, NewStyle As Long
    Dim x As Long, Y As Long
    
    'получение текушего стиля окна
    OldStyle = GetWindowLong(frm.hwnd, STYLE)
    
    'определение и установка нового стиля окна
    NewStyle = (OldStyle And Not CAPTION) Or BORDER
    SetWindowLong frm.hwnd, STYLE%, NewStyle
    
    'настройка размеров окна
    x = frm.Width \ IndexX
    Y = frm.Section(acDetail).Height \ IndexY
    
    'отображение окна с новыми свойствами
    SetWindowPos frm.hwnd, 0, 0, 0, x, Y, NOMOVE Or NOZODER Or FRAMECHANGED

End Function

Microsoft Access. Управление редактором RTF из Access

Данный пример показывает как можно редактировать тексты rtf в Microsoft Access (..\05 Конверторы\la_convert.accdb).

'сохранение текущей записи в файле в формате RTF
Private Sub cmdSave_Click()
    Me.RichTextBox1.SaveFile CurrentProject.Path  "\rtftemp"  Me.ID  ".rtf"
End Sub

'сохранение всех записей в файле в формате RTF
Private Sub cmdSaveAll_Click()
Dim i As Long, p As Long
Dim strtemp As String, strrtf As String
    'разделитель записей (по желанию)
    Const spl = "\rtf1\ansi\ansicpg1251\deff0\deflang1049{\fonttbl{\f0\fnil\fcharset0 Tahoma;}}"  _
    "\viewkind4\uc1\pard\f0\fs24 ************************************"  _
    "\par"
    
    'сведем все записи воедино
    DoCmd.GoToRecord , , acFirst
    DoCmd.Echo False
    For i = 1 To DCount("[ID]", "T1")
         strtemp = Me.RichTextBox1.TextRTF
         'для "нормального" склеивания фрагментов текста надо удалить лишние "}" "{"
         p = InStrRev(strtemp, "}")
         strtemp = Left(strtemp, p - 1)
         p = InStr(strtemp, "{")
         strtemp = Right(strtemp, Len(strtemp) - p)
         strrtf = strrtf  strtemp  spl
         DoCmd.GoToRecord , , acNext
    Next i
    DoCmd.GoToRecord , , acFirst
    DoCmd.Echo True
    
    'восстановим начальные и конечные "{"
    strrtf = "{"  strrtf  "}"
    
    'чтобы полученный не влиял на данные, отключим RichTextBox от данных
    strtemp = Me.RichTextBox1.ControlSource
    Me.RichTextBox1.ControlSource = ""
    Me.RichTextBox1.TextRTF = strrtf
    
    Me.RichTextBox1.SaveFile CurrentProject.Path  "\rtftempall.rtf"
    
    'восстановим нормальную работу
    Me.RichTextBox1.ControlSource = strtemp
End Sub

'управление насыщенностью
Private Sub ctlBold_AfterUpdate()
    Select Case Me.ctlBold.Value
    Case -1
    Me.RichTextBox1.SelBold = True
    Case 0
    Me.RichTextBox1.SelBold = False
    End Select
    Me.RichTextBox1.SetFocus
End Sub

Microsoft Access. Как вызвать диалог открытия (закрытия) файлов

08. Это типовой диалог Windows, который позволяет выбрать файл. Есть диалог и Microsoft Office с аналогичными целями. Его смотрите в других примерах (14 Файлы).

'Структура файла, описание дано ниже
Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As Long
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As Long
End Type

'Функция открытия файла
Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" ( _
        FILENAME As OPENFILENAME) As Boolean

'Функция сохранения файла
Declare Function GetSaveFileName Lib "comdlg32.dll" Alias "GetSaveFileNameA" ( _
        FILENAME As OPENFILENAME) As Boolean

'Флажки для параметра OPENFILENAME.Flags
'  (например, OFN_FILEMUSTEXIST Or OFN_READONLY)
Const OFN_READONLY = H1
Const OFN_OVERWRITEPROMPT = H2
Const OFN_HIDEREADONLY = H4
Const OFN_NOCHANGEDIR = H8
Const OFN_SHOWHELP = H10
Const OFN_ENABLEHOOK = H20
Const OFN_ENABLETEMPLATE = H40
Const OFN_ENABLETEMPLATEHANDLE = H80
Const OFN_NOVALIDATE = H100
Const OFN_ALLOWMULTISELECT = H200
Const OFN_EXTENSIONDIFFERENT = H400
Const OFN_PATHMUSTEXIST = H800
Const OFN_FILEMUSTEXIST = H1000
Const OFN_CREATEPROMPT = H2000
Const OFN_SHAREAWARE = H4000
Const OFN_NOREADONLYRETURN = H8000
Const OFN_NOTESTFILECREATE = H10000

Const OFN_SHAREFALLTHROUGH = 2
Const OFN_SHARENOWARN = 1
Const OFN_SHAREWARN = 0

Dim OFNAME As OPENFILENAME 'Назначаем переменную для файла

'==============================================================
'   Назначение
'        Открытие окна диалога файлов
'   Параметры:
'        strFilter - строка фильтра
'        strIniFile - файл инициализации
'        strTitleDlg - заголовок окна
'        strDefExt - расширение по умолчанию
'        strCurDir - текущая папка
'
Public Function funGetOpenFileName( _
    hWnd As Long, _
    strFilter As String, _
    strIniFile As String, _
    strTitleDlg As String, _
    strDefExt As String, _
    strCurDir As String) As String
Dim Flag As Boolean
     'Заполним структуру перед вызовом GetOpenFileName
     With OFNAME
         .lStructSize = Len(OFNAME) 'Размер структуры в байтах
         .hwndOwner = hWnd 'Указатель окна
         .lpstrFilter = strFilter 'Фильтр отбора
         .nFilterIndex = 1 'Индекс первой пары строк фильтра
         .lpstrFile = strIniFile  String$(512 - Len(strIniFile), 0) 'Полное имя файла
         .nMaxFile = 511 'Размер буфера файла
         .lpstrFileTitle = String$(512, 0) 'Только имя файла окна
         .nMaxFileTitle = 511 'Размер буфера заголовка
         .lpstrTitle = strTitleDlg 'Заголовок окна диалога
         .flags = OFN_FILEMUSTEXIST 'Типы читаемых файлов
         .lpstrDefExt = strDefExt 'Расширение файла по умолчанию
         .lpstrInitialDir = strCurDir 'Каталог файлов по умолчанию
         .hInstance = 0 'Идентификатор блока данных для OFN_ENABLETEMPLATE
         .lpstrCustomFilter = 0 'Дополнительные фильтры, см. ниже
         .nMaxCustFilter = 0 'не менее 40, 0 - игнорируется
         .nFileOffset = 0 'Определяет смещение имени
         .nFileExtension = 0 'Определяет расширение
         .lCustData = 0 'Для собственных окон
         .lpfnHook = 0 'Указатель на функцию фильтра
         .lpTemplateName = 0 'Собственный диалог
         '*** Старт
         'If GetOpenFileName(OFNAME) = True Then  'Win 98 Попробуйте такой вариант
         Flag = GetOpenFileName(OFNAME) 'Общий случай
         If Flag Then  'Открываем диалог и находим имя файла
              funGetOpenFileName = Left(.lpstrFile, InStr(.lpstrFile, Chr(0)) - 1)
         Else
              funGetOpenFileName = ""
         End If
    End With
End Function

'==============================================================
'   Назначение
'        Открытие окна диалога файлов
'   Параметры:
'        strFilter - строка фильтра
'        strIniFile - файл инициализации
'        strTitleDlg - заголовок окна
'        strDefExt - расширение по умолчанию
'        strCurDir - текущая папка
'
Public Function funGetSaveFileName( _
    hWnd As Long, _
    strFilter As String, _
    strIniFile As String, _
    strTitleDlg As String, _
    strDefExt As String, _
    strCurDir As String) As String
Dim Flag As Boolean
     'Заполним структуру перед вызовом GetOpenFileName
     With OFNAME
         .lStructSize = Len(OFNAME) 'Размер структуры в байтах
         .hwndOwner = hWnd 'Указатель окна
         .lpstrFilter = strFilter 'Фильтр отбора
         .nFilterIndex = 1 'Индекс первой пары строк фильтра
         .lpstrFile = strIniFile  String$(512 - Len(strIniFile), 0) 'Полное имя файла
         .nMaxFile = 511 'Размер буфера файла
         .lpstrFileTitle = String$(512, 0) 'Только имя файла окна
         .nMaxFileTitle = 511 'Размер буфера заголовка
         .lpstrTitle = strTitleDlg 'Заголовок окна диалога
         .flags = OFN_FILEMUSTEXIST 'Типы читаемых файлов
         .lpstrDefExt = strDefExt 'Расширение файла по умолчанию
         .lpstrInitialDir = strCurDir 'Каталог файлов по умолчанию
         .hInstance = 0 'Идентификатор блока данных для OFN_ENABLETEMPLATE
         .lpstrCustomFilter = 0 'Дополнительные фильтры, см. ниже
         .nMaxCustFilter = 0 'не менее 40, 0 - игнорируется
         .nFileOffset = 0 'Определяет смещение имени
         .nFileExtension = 0 'Определяет расширение
         .lCustData = 0 'Для собственных окон
         .lpfnHook = 0 'Указатель на функцию фильтра
         .lpTemplateName = 0 'Собственный диалог
         '*** Старт
         'If GetOpenFileName(OFNAME) = True Then  'Win 98 Попробуйте такой вариант
         Flag = GetSaveFileName(OFNAME) 'Общий случай
         If Flag Then  'Открываем диалог и находим имя файла
              funGetSaveFileName = Left(.lpstrFile, InStr(.lpstrFile, Chr(0)) - 1)
         Else
              funGetSaveFileName = ""
         End If
    End With
End Function

Microsoft Access. Обработка ошибок разными методами

03. В ADO и DAO ошибки обрабатываются по разному, используйте этот пример для анализа действий вашей программы при аварийных выходах.

Option Compare Database
Option Explicit
'***************************************************************
' 03. Обработка ошибок разными методами
'***************************************************************

'==============================================================
' ADO. Обработка ошибок
Private Sub butADO_Click()
Dim cnn As New ADODB.Connection
Dim oneErr As ADODB.Error, s As String
    On Error Resume Next
    cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=?"
    ' Информация о всех ошибках
    s = "Список ошибок;------ ADO -------;"
    For Each oneErr In cnn.Errors
        s = s  "Описание;"  oneErr.Description  ";"
        s = s  "Номер;"  oneErr.Number  ";"
        s = s  "Имя приложения;"  oneErr.Source  ";"
        s = s  "SQLState;"  oneErr.SQLState  ";"
        s = s  "NativeError;"  oneErr.NativeError  ";"
        s = s  "Код справки;"  oneErr.HelpContext  ";"
        s = s  "Файл справки;"  oneErr.HelpFile  ";"
    Next
    ' Полная информация о последней ошибке
    s = s  "Последняя ошибка;------ ADO -------;"
    Me.listErrors.RowSource = s  funLastError 'Отображаем ошибку
    Resume Next
End Sub

'==============================================================
' DAO. Обработка ошибок
Private Sub butDAO_Click()
Dim dbs As DAO.Database
Dim oneErr As DAO.Error
Dim strmdb As String, s As String
    
    On Error Resume Next
    Set dbs = DBEngine.OpenDatabase("?", , 2 / 0) ' Генерируем ошибку
    'Err.Raise 11 ' Самостоятельный генератор ошибок
    
    ' Информация о всех ошибках
    s = "Список ошибок;------ DAO "  DAO.Version  " -------;"
    For Each oneErr In DBEngine.Errors
        s = s  "Описание;"  oneErr.Description  ";"
        s = s  "Номер;"  oneErr.Number  ";"
        s = s  "Имя приложения;"  oneErr.Source  ";"
    Next
    ' Полная информация о последней ошибке
    s = s  "Последняя ошибка;------ DAO -------;"
    Me.listErrors.RowSource = s  funLastError 'Отображаем ошибку
    Err.Clear
End Sub

'==============================================================
'  Возвращает информацию о последней ошибке
'  ADO и DAO
Private Function funLastError() As String
Dim s As String
    s = "Описание;"  Err.Description  ";"
    s = s  "Номер;"  Err.Number  ";"
    s = s  "Код справки;"  Err.HelpContext  ";"
    s = s  "Файл справки;"  Err.HelpFile  ";"
    s = s  "Имя приложения;"  Err.Source  ";"
    s = s  "DLL код;"  Err.LastDllError  ";"
    funLastError = s
End Function

Microsoft Access. Номер записи

04. Бывает в подчиненной таблице нужно определить, где находится курсор и какой номер записи. Параметр AbsolutePosition покажет вам решение этой задачи.

Private Sub Дата_GotFocus()
    With Me.Form.Recordset
        Me.Parent.NumberRecord = .AbsolutePosition + 1
        Me.Parent.PercentPosition = .PercentPosition
        Me.Parent.RecordCount = .RecordCount
        Me.Parent.Repaint
    End With
End Sub

Microsoft Access. Открытие базы данных разными методами

02. В этом примере показаны два разных метода открытия базы данных через ADO, DAO и использование файла udl

Option Compare Database
Option Explicit
'***************************************************************
' 02. Открытие базы данных разными методами
'***************************************************************

'==============================================================
' ADO. Открытие базы данных
Private Sub butADO_Click()
Dim cnn As ADODB.Connection ' Переменная для соединения
Dim myLinks As MSDASC.DataLinks ' Переменная для граф.интерфейса
   On Error GoTo 999
   ' Текущее соединение
   ' Set cnn = CurrentProject.Connection
   
   ' Определяем новое соединение
   Set cnn = New ADODB.Connection
   
   If Me.grOpen Then ' Графический интерфейс
        If Me.grOpen = 1 Then ' Графический интерфейс
         ' 1. Открытие соединения без файла
           cnn.Provider = "Microsoft.Jet.OLEDB.4.0"
           cnn.Mode = adModeReadWrite ' Открываем на чтение и запись
           cnn.Properties("User ID") = "Admin"
           cnn.Properties("Data Source") = CodeProject.Path  "\la_form.mdb"
        Else
           ' 2. Открываем соединение, используя файл udl (2 варианта открытия)
           On Error Resume Next
           cnn.Open
           cnn.Properties("Extended Properties") = "File Name="  CodeProject.Path  "\la_ado.udl"
           ' Дополнительный пример
           ' cnn.Open "File Name="  CodeProject.Path  "\la_ado.udl"
           cnn.Close
           Err.Clear
        End If
        ' Включаем редактор udl (см. также Tools/References ...)
        Set myLinks = New MSDASC.DataLinks
        myLinks.hWnd = Application.hWndAccessApp ' Родственник udl
        If myLinks.PromptEdit(cnn) = True Then ' Редактирование, OK = true
            cnn.Open
            cnn.Close
            ' Отображаем строку подключения
            Me.listCon.RowSource = cnn.ConnectionString
        Else
            ' Отображаем пустую строку подключения
            Me.listCon.RowSource = "Отмена соединения;"
        End If
        
        Set myLinks = Nothing ' Уничтожаем ссылку
   Else ' Программный интерфейс
        ' Определяем строку соединения для Microsoft.Jet.OLEDB
        ' Полностью определить переменные подключения для других провайдеров
        ' можно открыв файл udl, который создается в проводнике
        Dim strCnn As String
        strCnn = "Provider=Microsoft.Jet.OLEDB.4.0;" ' Провайдер
        strCnn = strCnn  "Data Source="  CurrentProject.Path  "\la_form.mdb;" ' база данных
        strCnn = strCnn  "User ID=Admin;" ' Пользователь
        strCnn = strCnn  "Mode=ReadWrite|Read;" ' Режим чтения и записи+другие свойства
        strCnn = strCnn  "Extended Properties='';" ' Расширенные свойства, например, файл udl
        strCnn = strCnn  "Persist Security Info=False;"
        strCnn = strCnn  "Locale Identifier=1033;"
        strCnn = strCnn  "Jet OLEDB:System database='';" 'C:\..\SYSTEM.MDW;
        strCnn = strCnn  "Jet OLEDB:Database Password='';" ' Пароль внутри базы
        strCnn = strCnn  "Jet OLEDB:New Database Password='';"
        strCnn = strCnn  "Jet OLEDB:Encrypt Database=False;"
        strCnn = strCnn  "Jet OLEDB:Create System Database=False;"
        strCnn = strCnn  "Jet OLEDB:Registry Path='';"
        strCnn = strCnn  "Jet OLEDB:Engine Type=5;"
        strCnn = strCnn  "Jet OLEDB:Database Locking Mode=1;"
        strCnn = strCnn  "Jet OLEDB:Global Partial Bulk Ops=2;"
        strCnn = strCnn  "Jet OLEDB:Global Bulk Transactions=1;"
        strCnn = strCnn  "Jet OLEDB:Don't Copy Locale on Compact=False;"
        strCnn = strCnn  "Jet OLEDB:SFP=False;"
        strCnn = strCnn  "Jet OLEDB:Compact Without Replica Repair=False;"
        
        ' Назначаем строку соединения
        cnn.ConnectionString = strCnn
        
        ' Отображаем строку подключения
        Me.listCon.RowSource = cnn.ConnectionString
        
        ' Открываем соединение
        cnn.Open
        cnn.Close
End If
    ' Конец
    Set cnn = Nothing
    Exit Sub
999:
    MsgBox Err.Description
    Err.Clear
End Sub

'==============================================================
' DAO. Открытие базы данных
Private Sub butDAO_Click()
Dim dbs As DAO.Database
    ' Текущая база
    ' Set dbs = CurrentDb
    
    ' Открываем новую базу
    Set dbs = DBEngine.OpenDatabase(CurrentProject.Path  "\la_form.mdb", , True)
    ' Отображаем строку подключения
    Me.listCon.RowSource = "DAO"
    
    ' Закрываем базу
    dbs.Close
    Set dbs = Nothing
    MsgBox "База открыта и закрыта (DAO)!", vbExclamation, "Лидер Access"
End Sub

Microsoft Access. Использование функции timeGetTime

08. Этот пример показывает как с использованием API интерфейса и функция времени в миллисекундах с момента запуска Windows оперелить время открытия формы

' Функция времени в миллисекундах с момента запуска Windows
Private Declare Function apiTimeGetTime Lib "winmm.dll" Alias "timeGetTime" () As Long
Dim T0 As Long, T1 As Long

Private Sub Form_Open(Cancel As Integer)
    ' Устанавливаем начальное значение
    T0 = apiTimeGetTime()
    ' Определяем список
    Me.myList.RowSource = Me.myList.RowSource  ";Form_Open: "  ";"  T0  ";"  0
End Sub
Private Sub Form_Activate()
    T1 = apiTimeGetTime()
    Me.myList.RowSource = Me.myList.RowSource  ";Form_Activate: "  ";"  T1  ";"  T1 - T0
End Sub
Private Sub Form_Current()
    T1 = apiTimeGetTime()
    Me.myList.RowSource = Me.myList.RowSource  ";Form_Current: "  ";"  T1  ";"  T1 - T0
End Sub
Private Sub Form_Load()
    T1 = apiTimeGetTime()
    Me.myList.RowSource = Me.myList.RowSource  ";Form_Load: "  ";"  T1  ";"  T1 - T0
End Sub
Private Sub Form_Resize()
    T1 = apiTimeGetTime()
    Me.myList.RowSource = Me.myList.RowSource  ";Form_Resize: "  ";"  T1  ";"  T1 - T0
End Sub