vba 在VBA中的特定页码上打开PDF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6361706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 13:29:05  来源:igfitidea点击:

Opening PDF on specific page number in VBA

ms-accessvba

提问by Colin

I am trying to create a button on my access form that allows for the user to view the corresponding page that goes with the data within the form (In this case, a part number is displayed on the form, and I want the button to open the Part Standard file to show the blueprint/diagram of said part)

我正在尝试在我的访问表单上创建一个按钮,允许用户查看与表单中的数据对应的页面(在这种情况下,表单上显示了一个部件号,我希望该按钮打开零件标准文件以显示所述零件的蓝图/图表)

I have tried using Adobe's page parameters #page=pagenum at the end of my filepath, but doing this doesn't work.

我曾尝试在文件路径的末尾使用 Adob​​e 的页面参数 #page=pagenum,但这样做不起作用。

Here is the code I have (Basic, I know) but I'm trying to figure out where to go here. I have simple condensed down my filepath, for obvious reasons - Note: It's not a URL, but a file path if this matters.

这是我的代码(基本的,我知道),但我想弄清楚该去哪里。出于显而易见的原因,我已经简单地压缩了我的文件路径 - 注意:如果这很重要,它不是一个 URL,而是一个文件路径。

Private Sub Command80_Click()

    Dim loc As String 'location of file

    'loc = Me.FileLoc
    loc = "G:\*\FileName.pdf#page=1"

    Debug.Print loc
    'Debug.Print Me.FileLoc
    'Debug.Print Me.FileName

    Application.FollowHyperlink loc

End Sub

Is this possible to do this way? I will continue to read other users posts in hopes to find a solution, and I'll note here if I do find one.

可以这样做吗?我将继续阅读其他用户的帖子,希望能找到解决方案,如果我找到了,我会在此注明。

Thanks!

谢谢!

Update

更新

I've found a way to do this, just I have 1 small complication now. My database will be accessed by many users, possibly with different versions of Acrobat, or different locations. Here is my workingcode:

我找到了一种方法来做到这一点,只是我现在有 1 个小问题。许多用户可能使用不同版本的 Acrobat 或不同的位置访问我的数据库。这是我的工作代码:

Private Sub Command2_Click()

pat1 = """C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe"""

pat2 = "/A ""page=20"""

pat3 = """G:\*\FileName.pdf"""

Shell pat1 & " " & pat2 & " " & pat3, vbNormalFocus

End Sub

Now, here is my concern. This code opens AcroRd32.exe from a specific file path, if my users have this stored elsewhere or have a different version, this won't work. Does anyone have a suggestion as how to possibly get around this?

现在,这是我的担忧。此代码从特定文件路径打开 AcroRd32.exe,如果我的用户将其存储在其他地方或使用其他版本,则这将不起作用。有没有人有关于如何解决这个问题的建议?

Thanks again! :)

再次感谢!:)

回答by mwolfe02

The correctway to do this is probably to look up the location of the acrobat reader executable in the system registry. I find that's generally more trouble than it's worth, especially if I have some control over all of the places my program will be installed (within a single intranet, for example). Usually I end up using this function that I wrote:

执行此操作的正确方法可能是在系统注册表中查找 acrobat reader 可执行文件的位置。我发现这通常比它的价值更麻烦,特别是如果我可以控制我的程序将安装的所有位置(例如在单个 Intranet 中)。通常我最终会使用我写的这个函数:

'---------------------------------------------------------------------------------------
' Procedure : FirstValidPath
' Author    : Mike
' Date      : 5/23/2008
' Purpose   : Returns the first valid path found in a list of potential paths.
' Usage     : Useful for locating files or folders that may be in different locations
'               on different users' computers.
' Notes     - Directories must be passed with a trailing "\" otherwise the function
'               will assume it is looking for a file with no extension.
'           - Returns Null if no valid path is found.
' 5/6/11    : Accept Null parameters.  If all parameters are Null, Null is returned.
'---------------------------------------------------------------------------------------
'
Function FirstValidPath(ParamArray Paths() As Variant) As Variant
Dim i As Integer

    FirstValidPath = Null
    If UBound(Paths) - LBound(Paths) >= 0 Then
        For i = LBound(Paths) To UBound(Paths)
            If Not IsNull(Paths(i)) Then
                If Len(Dir(Paths(i))) > 0 Then
                    FirstValidPath = Paths(i)
                    Exit For
                End If
            End If
        Next i
    End If

End Function

The function takes a parameter array so you can pass it as many or as few paths as necessary:

该函数接受一个参数数组,因此您可以根据需要传递尽可能多或尽可能少的路径:

PathToUse = FirstValidPath("C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe", _
                           "C:\Program Files\Acrobat\Reader.exe", _
                           "C:\Program Files (x86)\Acrobat\Reader.exe", _
                           "C:\Program Files\Acrobat\Reader.exe")
pat1 = """" & PathToUse & """"

回答by Levy

Registry keys are the better way to go, unlike file locations they have consistency between systems.

注册表项是更好的方法,与文件位置不同,它们在系统之间具有一致性。

Below are three functions, two in support of one, and a macro which tests the functions.

下面是三个函数,两个支持一个,以及一个测试这些函数的宏。

GetARE()(Get Adobe Reader Executable) returns the proper path based on a version search in a pre-defined location passed as the argument. This removes the hassle of typing out many different key locations for each version and provides some amount of coverage should future versions be released and installed on a user's system.

GetARE()(获取 Adob​​e Reader Executable)根据在作为参数传递的预定义位置中的版本搜索返回正确的路径。这消除了为每个版本键入许多不同关键位置的麻烦,并在将来的版本发布并安装在用户系统上时提供一定的覆盖范围。

I have installed previous versions of Reader to test whether or not the there is consistency in the InstallPath key location, up until quite outdated versions, there is. In fact, mwolfe02 and I both have our keys in the same location, though I am using version 11 and he, at the time of writing, was using 10. I was only able to test this on a x64 system, but you can easily modify the code below to search for both x64 and x86 keys. I expect a large corporation like Adobe to stick to their conventions, so this will likely work for quite some time without much modification even as new versions of Reader are released.

我已经安装了以前版本的 Reader 来测试 InstallPath 键位置是否存在一致性,直到相当过时的版本为止。事实上,mwolfe02 和我的密钥都在同一个位置,尽管我使用的是 11 版,而在撰写本文时他使用的是 10 版。我只能在 x64 系统上进行测试,但您可以轻松地修改下面的代码以搜索 x64 和 x86 键。我希望像 Adob​​e 这样的大公司坚持他们的惯例,因此即使发布了新版本的 Reader,这也可能会在很长一段时间内运行而无需进行太多修改。

I wrote this quickly, expect inefficiency and inconsistency in naming conventions.

我写得很快,预计命名约定效率低下和不一致。

Truly the best approach to ensure the path is almost-always returned would be to simply run a registry search through VBA in a loop for version numbers using "*/Acrobat Reader/XX.YY/InstallPath/" and then including the executable based on a check for the appropriate candidate in the appropriate directory; however, this isn't exactly a very cost-effective solution. My tests have shown that there is quite a bit of consistency between versions as to where the Install Path can be found, and as to what the executable name may be, so I opted for something more efficient if less lasting.

真正确保路径几乎总是返回的最佳方法是使用“*/Acrobat Reader/XX.YY/InstallPath/”在循环中通过 VBA 运行注册表搜索以获取版本号,然后包括基于在适当的目录中检查适当的候选人;然而,这并不是一个非常划算的解决方案。我的测试表明,在可以找到安装路径的位置以及可执行文件名称可能是什么方面,版本之间存在相当多的一致性,因此我选择了更有效但不那么持久的东西。

RegKeyRead()and RegKeyExists()were taken from:

RegKeyRead()RegKeyExists()取自:

http://vba-corner.livejournal.com/3054.html

http://vba-corner.livejournal.com/3054.html

I have not modified their code. Take into consideration saying thanks to the author of that post, the code is not complex by any means but it did save me the hassle of writing it myself.

我没有修改他们的代码。考虑到感谢那篇文章的作者,代码并不复杂,但它确实让我省去了自己编写代码的麻烦。

Function RegKeyRead(i_RegKey As String) As String
Dim myWS As Object

  On Error Resume Next
  'access Windows scripting
  Set myWS = CreateObject("WScript.Shell")
  'read key from registry
  RegKeyRead = myWS.RegRead(i_RegKey)
End Function
Function RegKeyExists(i_RegKey As String) As Boolean
Dim myWS As Object

  On Error GoTo ErrorHandler
  'access Windows scripting
  Set myWS = CreateObject("WScript.Shell")
  'try to read the registry key
  myWS.RegRead i_RegKey
  'key was found
  RegKeyExists = True
  Exit Function

ErrorHandler:
  'key was not found
  RegKeyExists = False
End Function
Function GetARE(i_RegKey As String) As String
    Dim InPath As String
    Dim InKey As String
    Dim Ind As Integer
    Dim PriVer As String
    Dim SubVer As String
    Dim Exists As Boolean

    Exists = False

    PriVer = 1
    SubVer = 0

    For Ind = 1 To 1000
        If SubVer > 9 Then
            PriVer = PriVer + 1
            SubVer = 0
        End If

        Exists = RegKeyExists(i_RegKey + "\" + PriVer + "." + SubVer + "\InstallPath\")
        SubVer = SubVer + 1

        If Exists = True Then
            SubVer = SubVer - 1
            InKey = i_RegKey + "\" + PriVer + "." + SubVer + "\InstallPath\"
            InPath = RegKeyRead(InKey)
            GetARE = InPath + "\AcroRd32.exe"
            Exit For
        End If
    Next     
End Function


Sub test()
    Dim rando As String

    rando = GetARIP("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Adobe\Acrobat Reader")

    MsgBox (rando)
End Sub

回答by Profex

Just to add to mwolfe02's answer, here is a function that tries to retrieve the executable for the file type given (it also uses the registry commands Levy referenced) :

只是为了添加到 mwolfe02 的答案中,这里有一个函数尝试检索给定文件类型的可执行文件(它还使用 Levy 引用的注册表命令):

Function GetShellFileCommand(FileType As String, Optional Command As String)
Const KEY_ROOT As String = "HKEY_CLASSES_ROOT\"
Dim sKey As String, sProgramClass As String
    ' All File Extensions should start with a "."
    If Left(FileType, 1) <> "." Then FileType = "." & FileType
    ' Check if the File Extension Key exists and Read the default string value
    sKey = KEY_ROOT & FileType & "\"
    If RegKeyExists(sKey) Then
        sProgramClass = RegKeyRead(sKey)
        sKey = KEY_ROOT & sProgramClass & "\shell\"
        If RegKeyExists(sKey) Then
            ' If no command was passed, check the "shell" default string value, for a default command
            If Command = vbNullString Then Command = RegKeyRead(sKey)
            ' If no Default command was found, default to "Open"
            If Command = vbNullString Then Command = "Open"
            ' Check for the command
            If RegKeyExists(sKey & Command & "\command\") Then GetShellFileCommand = RegKeyRead(sKey & Command & "\command\")
        End If
    End If
End Function

so,

所以,

Debug.Print GetShellFileEx("PDF")

outputs:

输出:

"C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe" "%1"

and you just have to replace the "%1" with the file you want to open and add any parameters you need.

您只需将“%1”替换为您要打开的文件并添加您需要的任何参数。

回答by user4995576

Here is code the probably you can use..

这是您可能可以使用的代码..

Private Sub CommandButton3_Click()

  Dim strFile As String

  R = 0

  If TextBox7 = "CL" Then
    R = 2
    ' Path and filename of PDF file
    strFile = "E:\Users\Test\Cupertino Current system.pdf"
    ActiveWorkbook.FollowHyperlink strFile
  End If

  if R = 0 Then
    MsgBox "Wrong Code"
    ComboBox1 = ""
    TextBox1 = Empty
    'ComboBox1.SetFocus
  End If

End Sub

Just need to the right path.. Hope this can help you

只需要正确的道路..希望这可以帮助你

回答by Philippe Grondier

I remember that Acrobat reader used to include some ActiveX PDF reader object available for further use with Microsoft Office. Other companies have developed similar products, some of them (in their basic form) even available for free.

我记得 Acrobat 阅读器曾经包含一些 ActiveX PDF 阅读器对象,可用于进一步与 Microsoft Office 一起使用。其他公司也开发了类似的产品,其中一些(以基本形式)甚至免费提供。

That could be a solution, couldn't it? You'd have then to check that your activeX PDF reader supports direct page access in its methods, and distribute it with your apps, or have it installed on your user's computers. It will avoid you all the overhead related to acrobat readers versions follow-up, specially when newer versions will be available on the market and you'll have to update your client interface.

这可能是一个解决方案,不是吗?然后,您必须检查您的 ActiveX PDF 阅读器在其方法中是否支持直接页面访问,并将其与您的应用程序一起分发,或者将其安装在您用户的计算机上。它将避免您与 acrobat 阅读器版本后续相关的所有开销,特别是当市场上有新版本可用时,您必须更新您的客户端界面。