未看到来自 Excel VBA 的 PDF 字段
Not seeing PDF fields from Excel VBA
我的任务是创建一个 Excel 工具来将数以千计的 PDF 中的数据导入 Excel。我已经安装了 Adobe Acrobat X Professional,它似乎工作正常。我正在使用 Excel 2007.
我在这里找到了示例代码:
http://khkonsulting.com/2010/09/reading-pdf-form-fields-with-vba/
稍微修改它以提示我浏览到 PDF 文件,并设置对 "Adobe Acrobat 10.0 Type Library" 的引用,我正在尝试此代码:
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 方法。然后我得到错误 "Object required".
如果我在 AcroApp、theForm 和 jso 上 运行 TypeName,我将分别得到 CAcroApp、CAcroPDDoc 和对象:
?typename(AcroApp)
CAcroApp
?typename(theForm)
CAcroPDDoc
?typename(jso)
Object
如果我将它们放在 Watches window 中,我最初会在所有三个的左侧看到加号,但如果我单击这些加号,则每个加号下方只会出现一行,说值列中的“<无变量>”。
我想知道文档是否以某种方式被锁定以防止以这种方式阅读。我读到如果它被锁定,一个挂锁会出现在 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 中 window。
但是,它不显示方法创建的对象,例如AcroExch.PDDoc.GetJSObject方法创建的对象(参见对象模型中的AcroPDDoc)。此处使用的那个对象的方法 getNthFieldName 根本不会出现在对象浏览器中。
而且,我看不到任何其他方法可以通过字段的短名称来识别字段。
所以...对于这个项目,我将使用 getNthFieldName 返回的长字段名称。
iTextSharp 更容易使用!
也就是说,这里有一个片段可以读取所有字段。
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
可能是您的 "form" 没有任何字段(或扁平化表单),或者名称不正确。
JSObject 属性有点神秘。我找到了一个 post,它使用反射来提取数据,但碰巧 JSObject 属性是可用的,如果你知道它们是什么的话!例如numfields,getNthFieldName
如果有人找到 JSObject 的参考 link,请在评论中 post。
在 Adobe Acrobat OLE documentation but connsider using the AvDoc (UI) object as a "middle man" between document and app (Form < UI < App
). Essentially, the AvDoc 中不太直观的是用户与之交互的用户界面对象,而 PDDoc 是用户看不到但 Adobe Acrobat 保持访问权限的背景对象。
也请注意,我使用 formDoc
打开文档,这是一个不同于 JSObject 的 PDDoc,因为 formDoc
继承自 AVDoc 对象。同样,这种自动化没有很好的记录,因为 Adobe 更倾向于 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
我的任务是创建一个 Excel 工具来将数以千计的 PDF 中的数据导入 Excel。我已经安装了 Adobe Acrobat X Professional,它似乎工作正常。我正在使用 Excel 2007.
我在这里找到了示例代码: http://khkonsulting.com/2010/09/reading-pdf-form-fields-with-vba/
稍微修改它以提示我浏览到 PDF 文件,并设置对 "Adobe Acrobat 10.0 Type Library" 的引用,我正在尝试此代码:
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 方法。然后我得到错误 "Object required".
如果我在 AcroApp、theForm 和 jso 上 运行 TypeName,我将分别得到 CAcroApp、CAcroPDDoc 和对象:
?typename(AcroApp)
CAcroApp
?typename(theForm)
CAcroPDDoc
?typename(jso)
Object
如果我将它们放在 Watches window 中,我最初会在所有三个的左侧看到加号,但如果我单击这些加号,则每个加号下方只会出现一行,说值列中的“<无变量>”。
我想知道文档是否以某种方式被锁定以防止以这种方式阅读。我读到如果它被锁定,一个挂锁会出现在 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 中 window。
但是,它不显示方法创建的对象,例如AcroExch.PDDoc.GetJSObject方法创建的对象(参见对象模型中的AcroPDDoc)。此处使用的那个对象的方法 getNthFieldName 根本不会出现在对象浏览器中。
而且,我看不到任何其他方法可以通过字段的短名称来识别字段。
所以...对于这个项目,我将使用 getNthFieldName 返回的长字段名称。
iTextSharp 更容易使用!
也就是说,这里有一个片段可以读取所有字段。
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
可能是您的 "form" 没有任何字段(或扁平化表单),或者名称不正确。
JSObject 属性有点神秘。我找到了一个 post,它使用反射来提取数据,但碰巧 JSObject 属性是可用的,如果你知道它们是什么的话!例如numfields,getNthFieldName
如果有人找到 JSObject 的参考 link,请在评论中 post。
在 Adobe Acrobat OLE documentation but connsider using the AvDoc (UI) object as a "middle man" between document and app (Form < UI < App
). Essentially, the AvDoc 中不太直观的是用户与之交互的用户界面对象,而 PDDoc 是用户看不到但 Adobe Acrobat 保持访问权限的背景对象。
也请注意,我使用 formDoc
打开文档,这是一个不同于 JSObject 的 PDDoc,因为 formDoc
继承自 AVDoc 对象。同样,这种自动化没有很好的记录,因为 Adobe 更倾向于 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