How to export text from annotation fields in Nuance Power PDF to Excel using VBA? - excel

I am trying to export some text from annotation fields in Nuance Power PDF to Excel using VBA. I added the Nuance Power PDF reference to Excel VBA (PDF Plus).
I used it and it works well but the text returned from fields is empty.
Set PDFApp = CreateObject("NuancePDF.App")
Set dvDoc = CreateObject("NuancePDF.DVDoc")
dvDoc.Open("\\adpdc-2\Users$\a.goudinoux\Documents\Macro Formulaire\fiche.pdf")
Set ddDoc = dvDoc.GetDDDoc()
Set ddPage = ddDoc.AcquirePage(0)
nbannots = ddPage.GetNumAnnots() - 1
For i = 0 To nbannots
Texte = ""
Set ddAnnot = ddPage.GetAnnot(i)
Set ddText = ddDoc.CreateTextSelect(0, ddAnnot.GetRect())
ThisWorkbook.Sheets(1).Cells(1, i) = ddAnnot.GetTitle()
For k = 0 To ddText.GetNumText()
Texte = Texte & ddText.GetText(k)
Next
ThisWorkbook.Sheets(1).Cells(2, i) = Texte
Next
Part of the PDF document :
Results :
As you can see the first line is working but not the second one.
I thought the problem was with ddText but ddText.GetNumText() gives the right number of text elements in the text selection (ex : 2, 5, 4, etc...) when I run my program in Debug Mode.
I think the problem is from the function GetText(k).
I made it work once but I can't find my code back..
Do you see any mistake ?

Either your annotations are more complex than indicated or you're overthinking it.
Just read the annotation with GetContents and call it a day.
Set PDFApp = CreateObject("NuancePDF.App")
Set dvDoc = CreateObject("NuancePDF.DVDoc")
dvDoc.Open("\\adpdc-2\Users$\a.goudinoux\Documents\Macro Formulaire\fiche.pdf")
Set ddDoc = dvDoc.GetDDDoc()
Set ddPage = ddDoc.AcquirePage(0)
nbannots = ddPage.GetNumAnnots() - 1
For i = 0 To nbannots
Set ddAnnot = ddPage.GetAnnot(i)
ThisWorkbook.Sheets(1).Cells(1, i) = ddAnnot.GetTitle
ThisWorkbook.Sheets(1).Cells(2, i) = ddAnnot.GetContents
Next i

Related

Wildcards/patterns with .Tables("PARA") when executing RFC INST_EXECUTE_REPORT

I'm using Excel and VBA to get SAP to download data from SAP through RFC using INST_EXECUTE_REPORT.
It works like a charm when I have specific input parameters. I just build up .Tables("PARA") with the screen name of the parameter and the desired value. I can even use this method for date ranges.
The challenge is when I don't know exactly the input parameters. For example, I wanted to identify all internal orders with a specific text in the description, e.g. CODE40.
Is there any way to use wildcards with INST_EXECUTE_REPORT? When the program passed into INST_EXECUTE_REPORT is executed normally as a transaction on screen, I can set the parameter to *CODE40* and SAP automatically applies a wildcard search. But I can't get that to work with VBA.
I can simulate using wildcards when accessing individual tables with BBP_RFC_READ_TABLE by using LIKE statements in the selection option, but I need a similar functionality for whole reports, not individual tables.
Can anyone help?
Best regards,
The code I'm using is as follows:
Set ObjR3_EXECUTE_REPORT = ObjR3.Add("INST_EXECUTE_REPORT")
With ObjR3_EXECUTE_REPORT
Set ObjR3_EXECUTE_REPORT_Name = .Exports("PROGRAM")
Set ObjR3_EXECUTE_REPORT_Para = .Tables("PARA")
Set ObjR3_EXECUTE_REPORT_Result = .Tables("RESULT_TAB")
Set ObjR3_EXECUTE_REPORT_Output = .Tables("OUTPUT_TAB")
End With
ObjR3_EXECUTE_REPORT_Name.Value = ReportName
'Build up the table with the fields to be selected
f = 1
For a = LBound(aParameters) To UBound(aParameters)
aParameterPair = aParameters(a)
aParameterInput = aParameterPair(UBound(aParameterPair))
sParameterName = aParameterPair(LBound(aParameterPair))
For c = LBound(aParameterInput) To UBound(aParameterInput)
sParameterInput = aParameterInput(c)
ObjR3_EXECUTE_REPORT_Para.AppendRow
ObjR3_EXECUTE_REPORT_Para(f, "PARA_NAME") = sParameterName
ObjR3_EXECUTE_REPORT_Para(f, "PARA_VALUE") = sParameterInput
Debug.Print sParameterName & " " & sParameterInput
f = f + 1
Next c
Next a

How to use Autofill/Filldown with a range of values

I have been trying to get Excel to apply a formula over a set of columns and then extend the pattern across the entire set of rows.
This has led to the following code:
For i = 0 To avgsheetNames.Count - 1
If Contains(CStr(avgsheetNames(i)), "Scores") = True Then
With mainWorkBook.Worksheets(avgsheetNames(i))
strFormulas(1) = "=SUM(Aggregated_Internal_Scores!I2:I7)/6"
strFormulas(2) = "=SUM(Aggregated_Internal_Scores!J2:J7)/6"
strFormulas(3) = "=SUM(Aggregated_Internal_Scores!K2:K7)/6"
strFormulas(4) = "=SUM(Aggregated_Internal_Scores!L2:L7)/6"
strFormulas(5) = "=SUM(Aggregated_Internal_Scores!M2:M7)/6"
strFormulas(6) = "=SUM(Aggregated_Internal_Scores!N2:N7)/6"
strFormulas2(1) = "=SUM(Aggregated_Internal_Scores!I8:I13)/6"
strFormulas2(2) = "=SUM(Aggregated_Internal_Scores!J8:J13)/6"
strFormulas2(3) = "=SUM(Aggregated_Internal_Scores!K8:K13)/6"
strFormulas2(4) = "=SUM(Aggregated_Internal_Scores!L8:L13)/6"
strFormulas2(5) = "=SUM(Aggregated_Internal_Scores!M8:M13)/6"
strFormulas2(6) = "=SUM(Aggregated_Internal_Scores!N8:N13)/6"
mainWorkBook.Worksheets(avgsheetNames(i)).Range("C2:H2").Formula = strFormulas
mainWorkBook.Worksheets(avgsheetNames(i)).Range("C3:H3").Formula = strFormulas2
mainWorkBook.Worksheets(avgsheetNames(i)).Range("C2:H3").AutoFill Destination:=mainWorkBook.Worksheets(avgsheetNames(i)).Range("C2:H32")
End With
End If
As you can see I have tried to provide the pattern I am going for where the values extracted from the "Aggregated_Internal_Scores" sheet should follow the pattern I2:I7 > I8:I13 > I14:I19 and so on.
However, when the macro has been executed what I get is I2:I7 > I8:I13 > I4:I9 > I10:I15?
It seems Excel is taking the block C2:H3 as the pattern and just incrementing by 2 at the start of every block.
Can you anyone explain where I have gone wrong and how I can specify that I want the extraction of sheet values to follow a certain pattern?
Thank you in advance!
Use:
mainWorkBook.Worksheets(avgsheetNames(i)).Range("C2:H32").Formula = "=SUM(INDEX(Aggregated_Internal_Scores!I:I,(ROW($ZZ1)-1)*6+2):INDEX(Aggregated_Internal_Scores!I:I,(ROW($ZZ1)-1)*6+7))/6"
Replace everything inside the If with that.
If one has Office 365 with dynamic array formula then use:
mainWorkBook.Worksheets(avgsheetNames(i)).Range("C2:H32").Formula2 = "=SUM(INDEX(Aggregated_Internal_Scores!I:I,SEQUENCE(6,,(ROW($ZZ1)-1)*6+2))/6"

How can i add this other condition to this code?

i have this subroutine that i use to make labels. for some reason i cant just make another subroutine where instead of "CGI_SAMPLE_LABEL" it uses "YCI_SAMPLE_LABEL" because of other subroutines. any suggestions on how i can add this so that it chooses either one or the other. if tried using WHERE OR but that didn't work. i edited some of the tags because LIMS basic language is also like smalltalk.
LabelType = "CGI_SAMPLE_LABEL"
pTableNameStr = "SAMPLE"
pLabelNameStr = "CGI_SAMPLE_LABEL"
'Breakpoint(aReason)
NumSamples = Ubound(selectedObjects, 1)
FOR X = 1 TO NumSamples
SampleNumber = selectedObjects[x]
pKeyNameArr[1] = SampleNumber
pNumLabelsInt = 1
pLabelNameStr = "CGI_SAMPLE_LABEL"
pReasonStr = "Auto Label Generation"
pActivityStr = "Label printed for sample logged event"
GOSUB FN_LABEL_PRINT_ALL
NEXT 'Sample
RETURN

Load image to a label in userform using vba

I am working on a userform to load Images over labels, I am getting a
Run time error '75': Path/File access error
with below code,
dim solArr as variant
solArr = Split("1.jpg,2.jpg,3.jpg",",")
For i = LBound(solArr) To UBound(solArr)
'For rating image
Dim ratingImageName As String
ratingImageName = "D:\somepath" & "\" & solArr(i)
Set imageStar = UserForm1.Frame3.Controls.Add("Forms.Label.1")
imageStar.Top = 40 + (i * 50)
imageStar.Left = 420
imageStar.Height = 20
imageStar.Width = 100
imageStar.Picture = LoadPicture(ratingImageName)
Next
But, if i use ratingImageName as "D:\Somepath\1.jpg" no error is recieved...
Is there a better way to do it?
Hmmm.. solArr = Array("1.jpg","2.jpg","3.jpg")
I was picking up a value from cell as
1.jpg
2.jpg
3.jpg
the sentence replace(arrSol(i),chr(10),"") solved the problem.
Set imageStar = UserForm1.Frame3.Controls.Add("Forms.Label.1")
I have an array of many items in-game. Example item1, item2, item3... How to change index at item (Exemple item & i) and add a picture it item in label in Form.

VBA - trying to create XML based on multiple ranges

I am trying to create an output as a XML (save as text file + ".xml").
The layout of the XML is:
<file-info> (forsendelse)
<record-info>
..account#..
</record-info>
</file-info>
I have created a range of fields where the XML is written so that I can just "copy" from the spreadsheet into the text file.
I have tried the following:
With Worksheets("XML_generator")
Set forsendelse1 = .Range("G10:G31")
dat = forsendelse1.Value
Set fs = CreateObject("Scripting.FileSystemObject")
Set myrange1 = .Range("G32:G40")
dat = myrange1.Value
Set fs = CreateObject("Scripting.FileSystemObject")
Set myrange_acc = .Range("G41:G41")
dat = myrange_acc.Value
Set fs = CreateObject("Scripting.FileSystemObject")
Set myrange2 = .Range("G42:G73")
dat = myrange2.Value
Set fs = CreateObject("Scripting.FileSystemObject")
Set forsendelse2 = .Range("G74:G75")
dat = forsendelse2.Value
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.CreateTextFile(FPath & "Request_" & FName & "_" & FDate & ".xml", True)
End With
When I do this I only get the last range ("forsendelse2") in my XML. Does anyone have an idea on how to get this to work?
Please note:
"..account#.." is just one cell in the workbook. This is the main
data to change between exports.
Not using the built in XML generator, since I require blank tags to be exported as well due to validation
Splitting into 5 is so that I going forward can add more than one "record1 + ..account#.. + record2"
In the future I wish the result to look something like this:
<file-info> (forsendelse)
<record-info>
..account#.. (i.e "A2" from sheet)
</record-info>
<record-info>
..account#.. (i.e "A3" from sheet)
</record-info>
</file-info>
But since I haven't tried to do the "while loop" on this yet, firstly I hope someone can help me fix my Range issue :)
Thank you for taking your time!
Best regards
Andreas Petersen
If you want to build up a string from multiple parts then you need to append each part, like this:
dat = "stack"
dat = dat & "overflow"
dat = dat & ".com"
The value of dat will now be "stackoverflow.com".
Your code is overwriting the existing value rather than appending to it:
dat = "stack"
dat = "overflow"
dat = ".com"
The value of dat will now be ".com"
Other issues:
it's not clear why you are creating multiple FileSystemObjects that don't get used (only the last one gets used for anything)
it may be easier to use MSXML2 and build a DOMDocument rather than trying to create the XML as a string

Resources