objJSO.importXFAData not writing data to PDF form - excel

The following code will open and save the testing PDF in question, but will not write any of the values in the XML file referenced into the saved form. The PDF was created by Livecycle, hence the XFA reference in the code. For the life of me, I cannot figure out why this command is not executing and not returning an error if it is somehow faulty.
Sub LoopTrial()
Dim strPDFPath As String
Dim MyFile As String
MyPath = "H:\Testing\Forms\"
strPDFPath = "H:\Testing\Test Form.pdf"
myExtension = "1.xml"
MyFile = MyPath & myExtension
'Loop
'Do While MyFile <> ""
Set objAcroApp = CreateObject("AcroExch.App")
Set objAcroAVDoc = CreateObject("AcroExch.AVDoc")
If objAcroAVDoc.Open(strPDFPath, "") = True Then
Set objAcroPDDoc = objAcroAVDoc.GetPDDoc
Set objJSO = objAcroPDDoc.GetJSObject
End If
objJSO.importXFAData MyFile
i = i + 1
strPDFOutPath = "H:\Testing\Forms\Form" & i & ".pdf"
objAcroPDDoc.Save 1, strPDFOutPath
objAcroApp.Exit
'Loop
End Sub

For security reasons, the importXFAData method is only allowed in batch and console events. You won't be able to execute it directly via VBA. You'll need to create a trusted function first and load it as an application level JavaScript, then call the trusted function. You'll also need to convert your path that will be a parameter for the JSO from Windows format to one that Acrobat JavaScript will understand... something like...
"C/foo/data.xfa"
for...
"C:\foo\data.xfa"
To create a trusted function, create a JavaScript (.js) file and load it into the Acrobat application JavaScript folder. It will look like this...
trustedImportXFAData = app.trustedFunction( function (pathToXFA)
{
// Additional code may appear above
app.beginPriv(); // Explicitly raise privilege
this.importXFAData(pathToXFA); //"this" being the form document
app.endPriv();
// Additional code may appear below.
})
The from VBA you'll call it the same way.
objJSO.trustedImportXFAData MyFile

Related

Modify and replace an XML file through a Macro to the same path (Excel VBA)

I have a custom-button in my excel sheet, and when the user clicks it, the code enables the user to upload a file, and then code modifies the uploaded file, and stores the modified contents in a String variable s. -
Option Explicit
Sub Button1_Click()
Dim fso As Object, ts As Object, doc As Object
Dim data As Object, filename As String
Dim ws As Worksheet
Set ws = ActiveSheet
' select file
With Application.FileDialog(msoFileDialogFilePicker)
If .Show <> -1 Then Exit Sub
filename = .SelectedItems(1)
End With
' read file and add top level
Set doc = CreateObject("MSXML2.DOMDocument.6.0")
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpentextFile(filename)
doc.LoadXML Replace(ts.readall, "<metadata>", "<root><metadata>", 1, 1) & "</root>"
ts.Close
' import data tag only
Dim s As String
Set data = doc.getElementsByTagName("data")(0)
s = data.XML
' MsgBox s
' replace the original XML file with contents of variable s here
If MsgBox(s & vbCrLf, vbYesNo) = vbYes Then
Application.SendKeys ("%lt")
Else
MsgBox "Ok"
End If
End Sub
Let's say I clicked the button and uploaded an XML file C:/My Folder/sample.xml. Now the code modifies it, and updates the file (with the new contents stored in variable s). Here's a representative image - (the modified contents is direct value of s variable)
How do I achieve the above? Kindly guide... Thanks!
See CreateTextFile method of a TextStream Objects
Set ts = fso.CreateTextFile(filename, True)
ts.Write s
ts.Close
Why not continue with XML methods by loading the wanted string again (after Set data = doc.getElementsByTagName("data")(0)):
doc.LoadXML data.XML
doc.Save filename
Side note to posted code
It's worth mentioning that the somehow peculiar insertion of a starting <root> and closing </root> tag into the loading xml string via
doc.LoadXML Replace(ts.readall, "<metadata>", "<root><metadata>", 1, 1) & "</root>"
is a only a workaround rebuilding a well-formed xml input thus avoiding
Error `-1072896683 XML document must have a top level element.`
So imo you might consider changing your pattern files to include metadata not at top-level, but at a subsequent hierarchy level already in design to provide for a loadable, well-formed xml markup.

Get only the PDF files

I have a little problem with my code in VBA, How can I exclude the other extension file like .txt, .csv, .xlsx, and .xlsm so I can select only in my For Each Loop is the .PDF extension only.
I've already searched about this issue and already tried, But the solution is not applicable in my code.
This is my code:
Option Explicit
Sub GetPDFFile()
Dim mainWs As Worksheet
Dim pdfPath As Variant, excelPath As Variant
Dim fileSystemObject As New fileSystemObject
Dim getFolderPath As Folder
Dim getFile As file
Dim wb As Workbook
Set mainWs = ThisWorkbook.Sheets("Main")
pdfPath = mainWs.Range("C7").Value
excelPath = mainWs.Range("C8").Value
'Set all variable to null
Call SetNothing
If pdfPath = "" Then
Call MsgActionInvalid("Please input PDF File Folder.")
ElseIf excelPath = "" Then
Call MsgActionInvalid("Please input Output Folder Location.")
Else
Set getFolderPath = fileSystemObject.getFolder(pdfPath)
Set wa = CreateObject("word.application")
If cntFiles <> 0 Then
For Each getFile In getFolderPath.Files
`Other code............
Next
End Sub
I'm getting all the files inside the folder that I've selected. So inside the For Each Loop I'm getting a debug message because the file is not .PDF.
Any ideas about this guys?
Thanks in advance.
Use the Type property of the File object like getFile.Type to find out its type. And use a If statement to run your Other code............ only on the desired type of files.
Alternatively use UCase(getFile) Like "*.PDF" to make sure that it is not case sensitive. Otherwise you only trigger .PDF but not .Pdf or .pdf or .pDf or whatever.
Which is the same as UCase(Right$(getFile, 4)) = ".PDF"
You should be using Right to check the file extension. Something like:
For Each getFile In getFolderPath.Files
If Right(getFile, 4) = ".pdf" Then
' have found a PDF extension............
End If
Next
Regards,

Excel VBA code is not supporting to save a PPT at custom location with custom name

I am currently trying to write a short Excel VBA code which 1) create, 2) edit 3) save and 4) close a PowerPoint Presentation.
This can be done using the standard code which saves a file at a hard coded location. However, I am trying to write code in this way that it will pop-up two input boxes and will ask for your 1) custom name of file and 2) custom location where you want to save the file.
Code that I have trying to write is not giving any error message, but it is doesn't saving the file as well.
Sub Save_Presentation_at_custom_location()
Dim pPres As PowerPoint.Presentation
Set pApp = CreateObject("Powerpoint.Application")
pApp.Visible = True
Set pPres = pApp.Presentations.Add
pPres.Slides.Add 1, ppLayoutTitle
Filename = Application.InputBox("FileName") & ".PPTX"
Path = Application.InputBox("Path") & "\"
pPres.SaveAs Filename:="Path" & "FileName", FileFormat:=ppSaveAsDefault
pPres.Close
End Sub
Your issue is that you saved the strings with ""
Change:
pPres.SaveAs Filename:="Path" & "FileName", FileFormat:=ppSaveAsDefault
pPres.Close
to
pPres.SaveAs Filename:=Path & FileName, FileFormat:=ppSaveAsDefault
pPres.Close
Also your dimensions Filename, Path and pApp are not declared on the code you showed but I guess you did it in your real code

How do you open a pdf file with VBA code for a relative file path?

I am trying to find the command and correct coding to open a PDF file with a relative file path to the active excel file. The code below works fine as a link directly to the file. However, I just need this code snippet to find the PDF file that is sitting in the same file as the opened excel file and open accordingly.
Sub OpeningPDF()
'ThisWorkbook.FollowHyperlink "C:\Users\Michael\My Documents\totals\copy.pdf"
End Sub
I tried working with ThisWorkbook.path but nothing I tried with that worked or seemed to be outdate. Any help in this matter would be much appreciated.
I have found two solutions to this:
The first one is using the built-in Shell() function. This should automatically resolve the relative path (relative to the applications current working directory):
Public Sub StartExeWithArgument()
Dim strFilename As String
strFilename = "../folder/file.pdf"
Call Shell(strFilename, vbNormalFocus)
End Sub
The second one uses the Shell.Application COM Object and will basically do the same as the first one.
Sub runit()
Dim Shex As Object
Set Shex = CreateObject("Shell.Application")
tgtfile = "../folder/file.pdf"
Shex.Open (tgtfile)
End Sub
If you start with ThisWorkbook.Path and your relative-reference, then trim a layer off for every "..\" in the relative reference, you'll get the path.
Function RelativeToAbsolutePath(ByVal RelativePath As String) AS String
Dim TempStart AS String, TempEnd AS String
TempStart = ThisWorkbook.Path
TempEnd = RelativePath
If Left(TempEnd,1) = "\" Then TempEnd = Mid(TempEnd,1)
RelativeToAbsolutePath = ""
On Error GoTo FuncErr
While Left(TempEnd,3)="..\" AND InStrRev(TempStart,"\")>0
TempStart = Left(TempStart,InStrRev(TempStart,"\")-1) 'Remove 1 layer from Workbook path
TempEnd = Mid(TempEnd,4) 'Remove 1 instance of "..\"
Wend
RelativeToAbsolutePath = TempStart & "\" & TempEnd 'Stitch it all together
FuncErr: 'You may want a DIR(..) check to see if the file actually exists?
End Function
You can then open it with Shell

Using VBA in Excel 2010

We have been using VBA code for years with Excel 2003. I have about 70 files that I pull information from and compile it into one spreadsheet. This time, it only recognizes 3 of the 70. I do not get any errors. I noticed that all 3 recognized are the old version ".xls." and all not being recognized are the ".xlsx". The portion of the code that I think is causing the problem is below. Can anyone help?
Public currApp As String
Public i As String
Public recordC As String
Public excelI As Integer
Public intFileHandle As Integer
Public strRETP As String
Public errFile As String
Public Function loopFiles(ByVal sFolder As String, ByVal noI As Integer)
'This function will loop through all files in the selected folder
'to make sure that they are all of excel type
Dim FOLDER, files, file, FSO As Object
excelI = noI
'MsgBox excelI
i = 0
'Dim writeFile As Object
'writeFile = My.Computer.FileSystem.WriteAllText("D:\Test\test.txt", "sdgdfgds", False)
Dim cnn As Connection
Set cnn = New ADODB.Connection
currApp = ActiveWorkbook.path
errFile = currApp & "\errorFile.txt"
If emptyFile.FileExists(errFile) Then
Kill errFile
Else
'Do Nothing
End If
'cnn.Open "DSN=AUTOLIV"
'cnn.Open "D:\Work\Projects\Autoliv\Tax workshop\Tax Schedules\sox_questionnaire.mdb"
cnn.Open ("DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & currApp & "\tax_questionnaire.mdb")
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
Set FSO = CreateObject("Scripting.FileSystemObject")
'Upon each found excel file it will make a call to saveFiles.
If sFolder <> "" Then
Set FOLDER = FSO.getfolder(sFolder)
Set files = FOLDER.files
For Each file In files
'ONLY WORK WITH EXCEL FILES
If file.Type = "Microsoft Excel Worksheet" Then
Workbooks.Open fileName:=file.path
xlsx is a "macro-free" workbook. To use VBA in the new file format, the file must be saved as an xlsm file.
EDIT: I read the question too hastily. If you want to identify excel files from the FSO object, use file.Type LIKE "Microsoft Excel *" or similar. Or, check the file's extension against ".xls*"
EDIT
The whole concept of identifying the file type by looking at the file name is fundamentally flawed. It's too easily broken by changes to file extensions and/or the "type" texts associated with those descriptions. It's easily broken by, say, an image file named "file.xls". I would just try opening the file with Workbooks.Open and catch the error. I'd probably put this logic in a separate function:
Function OpenWorkbook(strPath As String) As Workbook
On Error GoTo ErrorLabel
Set OpenWorkbook = Workbooks.Open(strPath)
ExitLabel:
Exit Function
ErrorLabel:
If Err.Number = 1004 Then
Resume ExitLabel
Else
'other error handling code here
Resume ExitLabel
End If
End Function
Then you can consume the function like this:
Dim w As Workbook
Set w = OpenWorkbook(file.Path)
If Not (w Is Nothing) Then
'...
The problem you're having has to do with this line:
If file.Type = "Microsoft Excel Worksheet" Then
Try adding and replacing it with this:
// add these lines just AFTER the line 'For Each file In files'
IsXLFile = False
FilePath = file.path
FilePath2 = Right(FilePath, 5)
FilePath3 = Mid(FilePath2, InStr(1, FilePath2, ".") + 1)
If UCase(Left(FilePath3, 2)) = "XL" Then IsXLFile = True
// replace faulty line with this line
If IsXLFile = True Then
Let me know how it works. Yes, it'd be possible to compress the statements that start with FilePath into one expression but I left it like that for clarity. Vote and accept the answer if good and follow-up if not.
Have a nice day.

Resources