【问题标题】:Not seeing PDF fields from Excel VBA看不到 Excel VBA 中的 PDF 字段
【发布时间】:2016-01-19 18:07:27
【问题描述】:

我的任务是创建一个 Excel 工具,将数据从数千个 PDF 导入 Excel。我已经安装了 Adob​​e Acrobat X Professional,它似乎工作正常。我正在使用 Excel 2007。

我在这里找到了示例代码: http://khkonsulting.com/2010/09/reading-pdf-form-fields-with-vba/

稍微修改一下以提示我浏览 PDF 文件,并设置对“Adobe Acrobat 10.0 类型库”的引用,我正在尝试此代码:

Sub Main()
Dim AcroApp As Acrobat.CAcroApp
Dim theForm As Acrobat.CAcroPDDoc
Dim jso As Object
Dim text1, text2 As String

Set AcroApp = CreateObject("AcroExch.App")
Set theForm = CreateObject("AcroExch.PDDoc")

Dim strFullPath As String
strFullPath = Application.GetOpenFilename()
theForm.Open (strFullPath) 'theForm.Open ("C:\temp\sampleForm.pdf")

Set jso = theForm.GetJSObject

' get the information from the form fields Text1 and Text2
text1 = jso.getfield("MFR_ctrl33605579").Value 'jso.getfield("Text1").Value
'(etc)
End Sub

(“MFR_ctrl33605579”是其中一个文本字段的名称;我在 Acrobat Pro 的一部分或附带的编辑器中发现了它,称为“Adobe LiveCycle Designer”。)

它运行没有错误,直到它到达 getfield 方法。然后我收到错误“需要对象”。

如果我在 AcroApp、theForm 和 jso 上运行 TypeName,我将分别获得 CAcroApp、CAcroPDDoc 和 object:

?typename(AcroApp)
CAcroApp
?typename(theForm)
CAcroPDDoc
?typename(jso)
Object

如果我将它们放在 Watches 窗口中,我最初会在所有三个加号的左侧看到加号,但如果我单击这些加号,每个加号下只会出现一行,上面写着“”在值列中。

我想知道文档是否以某种方式被锁定以防止以这种方式阅读。我读到如果它被锁定,Acrobat 的左上角会出现一个挂锁,并且不允许另存为文本。但是我没有看到任何挂锁,它确实允许保存为纯文本。据我所知,它似乎没有被锁定。

有什么我可以尝试的建议吗?

更新:

我刚刚开始尝试这些建议,但我想指出,在尝试了 rheitzman 的 For 循环来获取字段名称(使用 getNthFieldName)之后,如果我将其用于字段名称,我发现我的代码可以工作:

form1[0].QuestionnaireForm[0].sbfrmProfile[0].sbfrmContact[0].sbfrmManufacturerDetails[0].MFR_ctrl33605579[0]

或者换句话说:

text1 = jso.getfield("MFR_form1[0].QuestionnaireForm[0].sbfrmProfile[0].sbfrmContact[0].sbfrmManufacturerDetails[0].MFR_ctrl33605579[0]").Value

这将使我能够通过很长的、显然完全合格的参考来识别字段,这将使我完成项目。但首先我要检查其他想法,看看是否只能通过短名称找到字段。

更新 2:

我现在看到我可以在对象浏览器中检查某些对象模型的一些细节(过滤 Acrobat 上的库),即使它没有显示在 Watch 窗口中。

但是,它不显示由方法创建的对象,例如由 AcroExch.PDDoc.GetJSObject 方法创建的对象(请参阅对象模型中的 AcroPDDoc)。此处使用的该对象的方法 getNthFieldName 根本不会出现在对象浏览器中。

而且,我没有看到任何其他方法可以通过短字段名称来识别字段。

所以...对于这个项目,我将使用 getNthFieldName 返回的长字段名称。

【问题讨论】:

  • 我认为这可能不是字段名称。它在那里出错,你得到“需要对象”。字段末尾是否有一些空格?如果您将字段名称更改为其他名称并使用该名称更新代码,是否会发生相同的错误?我的两分钱。
  • getNthFieldName 是 AcroPDDoc() 上的一个方法,至少在 JavaScript 引用中,所以也许其他一些属性和方法也是有效的。我认为 JSObject() 可能支持一个子集 - 我怀疑它可以用来创建对象。 JSObject 显然是一个 Interop 生物,在我能找到的任何地方都没有记录。
  • 这是一个列出属性和方法的 JavaScript 参考 - 不确定与 Acrobat 1.0 interop.dll adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/… 的重叠之处,请参阅打印页 10/11 获取 getNthFieldName。不记录对象,只列出它们。

标签: vba excel pdf acrobat


【解决方案1】:

iTextSharp 更易于使用!

也就是说,这是一个读取所有字段的 sn-p。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim pdfForm As Acrobat.AcroPDDoc
    Dim jso As Object ' ?
    Dim s As String = ""
    Dim i As Integer
    Dim strFullPath As String = "H:\OIS\ENFORCE\OPEN_BURN\Ag\temp\Open_Burn_Template_Out.pdf"
    Try
        pdfForm = New Acrobat.AcroPDDoc
        pdfForm.Open(strFullPath)
        jso = pdfForm.GetJSObject
        For i = 0 To jso.numfields() - 1
            s = jso.getNthFieldName(i)
            Debug.Print(s & ": " & jso.getField(s).value)
        Next
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

可能是您的“表单”没有任何字段(或扁平表单),或者名称已关闭。

JSObject 属性有点神秘。我发现了一篇使用反射来提取数据的帖子,但碰巧 JSObject 属性是可用的,如果你知道它们是什么!例如numfields,getNthFieldName

如果有人找到 JSObject 的参考链接,请在 cmets 中发布。

【讨论】:

  • 谢谢,我能够使用 getNthFieldName 来返回非常长的完整字段“名称”(它们看起来像完全限定的引用),这又在我的原始代码中起作用。上面我的更新中的详细信息。
  • 当您打开 PDF 进行编辑时,字段名称应与 AcroBat 中看到的表单字段定义相匹配。 (工具(右上角菜单栏)、表格、编辑)。创作者/程序可能选择了字段名称,可能为它们命名了一些可以在多个版本中引用的名称。
  • 我知道这篇文章已经快三年了,但如果有人通过这里:adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/Acro6JS.pdf 这是用于 pdf 的文档,adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/… 这是关于在 VBA 中使用但不是完整参考
【解决方案2】:

Adobe Acrobat OLE 文档中不是很直观,但考虑使用 AvDoc (UI) 对象作为文档和应用程序之间的“中间人” (Form < UI < App)。本质上,AvDoc 是用户与之交互的用户界面对象,而 PDDoc 是用户看不到但 Adob​​e Acrobat 保持访问权限的背景对象。

请注意,我使用formDoc 打开文档,这是一个不同的 PDDoc,而不是用于 JSObject 的那个,因为formDoc 继承自 AVDoc 对象。同样,由于 Adob​​e 更倾向于 Javascript 而不是 VBA,因此这种自动化没有得到很好的记录,因此这主要是通过反复试验来学习的。

Sub Main()
    Dim AcroApp As Acrobat.CAcroApp
    Dim formUI As Acrobat.CAcroAVDoc
    Dim srcDoc As Acrobat.CAcroPDDoc, formDoc As Acrobat.CAcroPDDoc
    Dim jso As Object
    Dim strFullPath As String, text1 As String, text2 As String

    Set AcroApp = CreateObject("AcroExch.App")
    Set formUI = CreateObject("AcroExch.AVDoc")
    Set srcDoc = CreateObject("AcroExch.PDDoc")

    strFullPath = Application.GetOpenFilename()
    srcDoc.Open (strFullPath)

    If formUI.Open(strFullPath, "") = True Then
        Set formDoc = formUI.GetPDDoc()        
        Set jso = formDoc.GetJSObject()

        ' EXTRACT FORM FIELDS' TEXT
         text1 = jso.GetField("MFR_ctrl33605579").Value    
    End If

   ' UNINTIALIZING PDF OBJECTS
    Set jso = Nothing
    Set formDoc = Nothing         
    Set srcDoc = Nothing 
    Set formUI = Nothing
    Set AcroApp = Nothing

End Sub

【讨论】:

  • 谢谢,这很有趣,但给我留下了和以前一样的问题。出于同样的原因,在同一行出现同样的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-14
  • 2016-11-22
  • 1970-01-01
  • 2019-12-14
  • 2013-12-30
  • 1970-01-01
  • 2014-06-29
相关资源
最近更新 更多