是否存在Access 2010 64bit的“打开文件”对话框?

时间:2011-01-20 12:10:20

标签: ms-access vba access-vba openfiledialog ms-access-2010

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

7 个答案:

答案 0 :(得分:7)

您可以使用内置文件对话框。访问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.

答案 1 :(得分:6)

我从未在打开的文件对话框中使用控件,因为它只是API调用的包装器。 Call the standard Windows File Open/Save dialog box此外,控件可能存在分发和版本控制问题,因此我会尽力避免使用它们。

答案 2 :(得分:3)

我正在解决这个问题很长一段时间......

你上面说的所有内容都有效,但还有最后一篇要补充的内容......在WITH OFN声明下你需要改变

.lStructSize = Len(ofn)

.lStructSize = LenB(ofn)

然后一切正常。

答案 3 :(得分:2)

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

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

这是唯一有效的方法。

答案 4 :(得分:1)

首先,“CommonDialog类”似乎不适用于32位版本的Office。它给出了相同的OleDb错误。正如其中一位评论者指出的那样,这不是您应该使用的控件。虽然可能有另一个ActiveX控件可供使用,但实际上无法保证它将在您要部署数据库的每台计算机上都可用。除了Office和其他程序之外,我的开发盒上还有Visual Studio 6,VS 2008和VS 2010,所有这些程序都提供了典型用户无法获得的ActiveX DLL。此外,其中许多库不可再发行,或构成独特的安装障碍,可能根本不值得麻烦。

到目前为止,最简单,最通用的解决方案是从Windows API调用“打开”对话框。它位于comdlg32.dll中,该版本可用于您可能定位的每个Windows版本,并且不对comdlg32.ocx施加任何依赖。它还提供了比使用ActiveX控件更好的性能,因为它不需要将额外的模块加载到内存中。

所需的代码也不是很复杂。您需要为函数GetOpenFileName提供声明,该声明将创建“打开”对话框。它需要一个参数,OPENFILENAME structure的实例,其中包含用于初始化对话框的信息,以及接收用户选择的文件的路径。所以你还需要提供这种结构的声明。 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本身,然后返回用户选择的文件的完整路径或空字符串({{1} })如果用户单击“取消”按钮。您可以在调用代码中测试返回值,以确定要采取的操作过程。

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

编写和测试此解决方案的最长部分实际上是尝试找到如何打开VBA编辑器并在Access中编写宏。对于那些使用主菜单“粘贴”和“保存”的人来说,功能区可能是一个伟大的发明,但是多么痛苦。我整天都在使用软件,但我仍然找不到东西。 [/咆哮]

答案 5 :(得分:0)

我错过了64位Access细节。你应该运行它是不太可能的,但如果你是,这篇文章供你考虑,解释你如何改变你的API调用工作 - 你必须使用新的长指针数据类型:

Compatibility Between the 32-bit and 64-bit Versions of Office 2010

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

但你应该真的问为什么你在使用64位Access。 MS完全没有建议任何人使用64位Office,除非他们有特定原因需要它(例如需要使用它提供的额外内存,特别是对于像复杂的Excel电子表格模型这样的东西)。访问绝对不是从转换到64位中获益的应用程序之一。

对该主题的详细讨论:

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

答案 6 :(得分:0)

我刚刚在64位版本的Excel 2013中解决此问题。

......的组合

  1. 在传递给{{1}的LongPtr结构中的3个项目(hwndOwnerhInstancelpfnHook)中使用OPENFILENAME数据类型}
  2. 获取GetOpenFileNameA结构的大小时,使用Len函数替换LenB函数(如Max Albanese所述)
  3. ...诀窍,感谢此处记录的指导: https://gpgonaccess.blogspot.co.uk/2010/03/work-in-progress-and-64-bit-vba.html

相关问题