5

如何获得 Access 2010 64bit 的打开文件对话框?通常我会使用通用对话框控件,但它是 32 位的,不能与 Access 2010 64 位一起使用。

4

7 回答 7

9

您可以使用内置的文件对话框。自 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 年开始,上述内容适用于运行时或普通版,也适用于 access 2010 的 32 位或 64 位版本。

于 2011-01-22T08:00:20.297 回答
6

我从来没有使用过打开文件对话框的控件,因为无论如何它只是 API 调用的包装器。 调用标准的 Windows 文件打开/保存对话框 此外,控件可能存在分发和版本控制问题,因此我尽量避免它们。

于 2011-01-20T19:04:41.673 回答
3

我在这个问题上工作了很长时间......

您在上面所说的所有内容都有效,但还有最后一点要添加...在 WITH OFN 声明下您需要更改

.lStructSize = Len(ofn)

.lStructSize = LenB(ofn)

然后一切正常。

于 2013-08-20T19:07:05.387 回答
2

这家伙有一个工具,可以生成与打开文件兼容的 64 位代码。它是免费软件。

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

这是唯一有效的方法。

于 2011-01-21T13:55:45.663 回答
1

首先,“CommonDialog 类”似乎无法在 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 中编写宏。对于使用主菜单进行“粘贴”和“保存”的人来说,功能区可能是一项伟大的发明,但真是太痛苦了。我整天都在使用软件,但我仍然找不到东西。[/咆哮]

于 2011-01-21T01:31:29.047 回答
0

我错过了 64 位访问详细信息。您不太可能运行它,但如果您是,这里有一篇文章供您考虑,它解释了您必须如何更改 API 调用才能工作——您必须使用新的长指针数据类型:

Office 2010 32 位和 64 位版本之间的兼容性

如果您相应地更改 API 代码,它应该可以在 64 位 Access 上正常工作。

但是您真的应该问为什么要使用 64 位 Access。MS 根本不建议任何人使用 64 位 Office,除非他们有特定的原因需要它(例如需要使用它提供的额外内存,特别是对于复杂的 Excel 电子表格模型等)。Access 绝对不是从转换为 64 位中受益匪浅的应用程序之一。

主题的详细讨论:

简而言之,大多数人不应该运行 64 位 Office,这正是您遇到的原因 - 它会导致外部依赖于 32 位组件和 API 的遗留代码失败。

于 2011-01-22T02:10:42.070 回答
0

我一直在努力在 64 位版本的 Excel 2013 中解决这个问题。

一个组合...

  1. 使用传递给的结构中的 3 个项目 ( , , )的LongPtr数据类型hwndOwnerhInstancelpfnHookOPENFILENAMEGetOpenFileNameA
  2. 获取结构体大小时用函数替换Len函数(如Max Albanese所说)LenBOPENFILENAME

...成功了,感谢此处记录的指导: https ://gpgonaccess.blogspot.co.uk/2010/03/work-in-progress-and-64-bit-vba.html

于 2017-08-01T16:21:59.850 回答