Есть ли диалог открытия файла для Access 2010 64bit? - PullRequest
4 голосов
/ 20 января 2011

Как получить диалоговое окно «Открыть файл» для Access 2010 64bit?Обычно я бы использовал общий диалоговый элемент управления, но он 32-битный и не может использоваться с 64-битным Access 2010.

Ответы [ 7 ]

7 голосов
/ 22 января 2011

Вы можете использовать встроенный файл диалога. Он был там с 2003 года доступа.

Dim f    As FileDialog 
Set f = Application.FileDialog(msoFileDialogFilePicker) 
f.Show 
MsgBox "file choose was " & f.SelectedItems(1) 

Вы можете поздно связать, если хотите:

выше потребностей: библиотека объектов Microsoft Office 14.0

Если вы удалите ссылку на библиотеку объектов 14.0, то следующее код будет работать без каких-либо ссылок:

Dim f    As Object 
Set f = Application.FileDialog(3) 
f.AllowMultiSelect = True 
f.Show 

MsgBox "file choosen = " & f.SelectedItems.Count 

Таким образом, вышеприведенная версия работает во время выполнения или в обычной редакции начиная с 2003 года, а также работает как для 32-, так и для 64-разрядных версий Access 2010.

6 голосов
/ 20 января 2011

Я никогда не использовал элемент управления для диалога открытия файла, так как он все равно является просто оболочкой для вызова API. Вызовите стандартное диалоговое окно открытия и сохранения файлов Windows Кроме того, могут быть проблемы с распространением и контролем версий с элементами управления, поэтому я стараюсь их избегать.

3 голосов
/ 20 августа 2013

Я долго работал с этой проблемой ...

Все, что вы сказали выше, работает, но есть один последний кусок, который нужно добавить ... в соответствии с декларацией WITH OFN вам нужно изменить

.lStructSize = Len(ofn)

до

.lStructSize = LenB(ofn)

И тогда все работает.

2 голосов
/ 21 января 2011

У этого парня есть инструмент, который генерирует 64-битный код для открытия файла. Это бесплатное программное обеспечение.

http://www.avenius.de/en/index.php?Products:IDBE_Tools

Это было единственное, что сработало.

1 голос
/ 21 января 2011

Прежде всего, «CommonDialog Class» даже не работает на 32-битной версии Office.Выдает ту же ошибку OleDb.Как указывает один из комментаторов, это не тот элемент управления, который вам следует использовать.И хотя вы могли бы использовать другой элемент управления ActiveX, на самом деле нет никакой гарантии, что он будет доступен на каждой машине, на которой вы хотите развернуть свою базу данных.На моем компьютере разработчика есть Visual Studio 6, VS 2008 и VS 2010, в дополнение к Office и другим программам, каждая из которых предоставляет библиотеки ActiveX DLL, которые обычные пользователи не могли ожидать.Кроме того, многие из этих библиотек не подлежат распространению, или создают уникальные препятствия для установки, которые могут просто не стоить проблем.

На сегодняшний день самое простое и универсальное решение - это вызвать диалог Открыть изWindows API. Он находится в comdlg32.dll, который доступен в каждой версии Windows, на которую вы, возможно, ориентируетесь, и не налагает никаких зависимостей на comdlg32.ocx.Он также обеспечивает лучшую производительность, чем использование элемента управления ActiveX, поскольку не требует загрузки дополнительного модуля в память.

Требуемый код также не очень сложен.Вам необходимо предоставить объявление для функции GetOpenFileName, которая создает диалоговое окно Открыть.Он принимает единственный параметр, экземпляр структуры OPENFILENAME , который содержит информацию, используемую для инициализации диалогового окна, а также получения пути к файлу, выбранному пользователем.Таким образом, вам также необходимо предоставить объявление этой структуры.Код в VBA будет выглядеть примерно так:

Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As String
    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 String
End Type

Private Declare Function GetOpenFileName Lib "comdlg32.dll" _
    Alias "GetOpenFileNameA" (ByRef lpofn As OPENFILENAME) As Long

Также есть пара констант, которые вы можете передать в качестве флагов для настройки поведения диалога.Для полноты, вот полный список:

Private Const OFN_ALLOWMULTISELECT As Long = &H200
Private Const OFN_CREATEPROMPT As Long = &H2000
Private Const OFN_ENABLEHOOK As Long = &H20
Private Const OFN_ENABLETEMPLATE As Long = &H40
Private Const OFN_ENABLETEMPLATEHANDLE As Long = &H80
Private Const OFN_EXPLORER As Long = &H80000
Private Const OFN_EXTENSIONDIFFERENT As Long = &H400
Private Const OFN_FILEMUSTEXIST As Long = &H1000
Private Const OFN_HIDEREADONLY As Long = &H4
Private Const OFN_LONGNAMES As Long = &H200000
Private Const OFN_NOCHANGEDIR As Long = &H8
Private Const OFN_NODEREFERENCELINKS As Long = &H100000
Private Const OFN_NOLONGNAMES As Long = &H40000
Private Const OFN_NONETWORKBUTTON As Long = &H20000
Private Const OFN_NOREADONLYRETURN As Long = &H8000&
Private Const OFN_NOTESTFILECREATE As Long = &H10000
Private Const OFN_NOVALIDATE As Long = &H100
Private Const OFN_OVERWRITEPROMPT As Long = &H2
Private Const OFN_PATHMUSTEXIST As Long = &H800
Private Const OFN_READONLY As Long = &H1
Private Const OFN_SHAREAWARE As Long = &H4000
Private Const OFN_SHAREFALLTHROUGH As Long = 2
Private Const OFN_SHAREWARN As Long = 0
Private Const OFN_SHARENOWARN As Long = 1
Private Const OFN_SHOWHELP As Long = &H10
Private Const OFS_MAXPATHNAME As Long = 260

А для удобства я обернул весь этот беспорядок внутри вспомогательной функции, которую вы можете вызывать из VBA.Он принимает в качестве параметров свойства, которые вам чаще всего необходимо установить для диалогового окна открытия файла, обрабатывает вызов самого Windows API, а затем возвращает либо полный путь к файлу, выбранному пользователем, либо пустую строку (vbNullString)если пользователь нажал кнопку «Отмена».Вы можете проверить возвращаемое значение в вызывающем коде, чтобы определить, какие действия предпринять.

'This function shows the Windows Open File dialog with the specified
' parameters, and either returns the full path to the selected file,
' or an empty string if the user cancels.
Public Function OpenFile(ByVal Title As String, ByVal Filter As String, _
    ByVal FilterIndex As Integer, ByVal StartPath As String, _
    Optional OwnerForm As Form = Nothing) As String

    'Create and populate an OPENFILENAME structure
    'using the specified parameters
    Dim ofn As OPENFILENAME
    With ofn
        .lStructSize = Len(ofn)
        If OwnerForm Is Nothing Then
            .hwndOwner = 0
        Else
            .hwndOwner = OwnerForm.Hwnd
        End If
        .lpstrFilter = Filter
        .nFilterIndex = FilterIndex
        .lpstrFile = Space$(1024) & vbNullChar & vbNullChar
        .nMaxFile = Len(ofn.lpstrFile)
        .lpstrFileTitle = vbNullChar & Space$(512) & vbNullChar & vbNullChar
        .nMaxFileTitle = Len(.lpstrFileTitle)
        .lpstrInitialDir = StartPath & vbNullChar & vbNullChar
        .lpstrTitle = Title
        .flags = OFN_FILEMUSTEXIST
    End With

    'Call the Windows API function to show the dialog
    If GetOpenFileName(ofn) = 0 Then
        'The user pressed cancel, so return an empty string
        OpenFile = vbNullString
    Else
        'The user selected a file, so remove the null-terminators
        ' and return the full path
        OpenFile = Trim$(Left$(ofn.lpstrFile, Len(ofn.lpstrFile) - 2))
    End If
End Function

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

Public Sub DoWork()
    'Set the filter string (patterns) for the open file dialog
    Dim strFilter As String
    strFilter = "Text Files (*.txt)" & vbNullChar & "*.txt*" & vbNullChar & _
                "All Files (*.*)" & vbNullChar & "*.*" & vbNullChar & vbNullChar

    'Show the open file dialog with the custom title, the filters specified
    ' above, and starting in the root directory of the C: drive.
    Dim strFileToOpen As String
    strFileToOpen = OpenFile("Choose a file to open", strFilter, 0, "C:\")

    'See if the user selected a file
    If strFileToOpen = vbNullString Then
        MsgBox "The user pressed the Cancel button."
    Else
        MsgBox "The user chose to open the following file: " & _
               vbNewLine & strFileToOpen 
    End If
End Sub

Самая длинная часть написания и тестирования этогоРешение на самом деле пытался найти, как открыть редактор VBA и написать макрос в Access.Лента может быть отличным изобретением для людей, которые используют меню «Вставить» и «Сохранить», но какая боль.Я провожу весь день, используя программное обеспечение, и я все еще не могу найти вещи.[/ Декламация]

0 голосов
/ 01 августа 2017

Я только что решил эту проблему в 64-разрядной версии Excel 2013.

Сочетание ...

  1. Использование типа данных LongPtr для 3 элементов (hwndOwner, hInstance, lpfnHook) в структуре OPENFILENAME, переданной GetOpenFileNameA
  2. Замена функции Len на функцию LenB при получении размера структуры OPENFILENAME (как упомянуто Максом Альбанезе)

... добился цели благодаря руководству, задокументированному здесь: https://gpgonaccess.blogspot.co.uk/2010/03/work-in-progress-and-64-bit-vba.html

0 голосов
/ 22 января 2011

Я пропустил детализацию 64-битного доступа.Маловероятно, что вы должны его запустить, но если вы это сделаете, вот статья для вашего рассмотрения, которая объясняет, как вы должны изменить свой вызов API для работы - вы должны использовать новый тип данных длинного указателя:

Совместимость между 32-разрядной и 64-разрядной версиями Office 2010

Если вы соответствующим образом измените код API, он должен нормально работать на 64-разрядном Access.

Но вы должны спросить, почему вы используете 64-битный доступ.MS на самом деле совсем не рекомендует, чтобы кто-либо использовал 64-битный Office, если у него нет особых причин, по которым он им нужен (например, необходимость использовать дополнительную память, которую он предоставляет, особенно для таких вещей, как сложные модели таблиц Excel).Access определенно не является одним из приложений, которое извлекает большую выгоду из преобразования в 64-разрядную версию.

Подробное обсуждение темы:

Короче говоря, большинство людей не должны запускать 64-битный Office, именно по той причине, с которой вы столкнулись - это вызывает устаревший код с внешними зависимостями на 32-битных компонентах.и API не работают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...