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
Objective: I'm using a python script to generate an excel report (contains lots of pivot tables).
Problem: Unable to figure out how to add multiple items to pivot table filter
I've figured out a cumbersome solution where I can create individual data sets that are pre-filtered so I don't need to filter them in the pivot table. However, this isn't really efficient or effective if somebody wants to swap the filter on the final excel report.
I'll use code I found online as an example:
import win32com.client
Excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
win32c = win32com.client.constants
wb = Excel.Workbooks.Add()
Sheet1 = wb.Worksheets("Sheet1")
TestData = [['Country','Name','Gender','Sign','Amount'],
['CH','Max' ,'M','Plus',123.4567],
['FR','Max' ,'M','Minus',-23.4567],
['CH','Max' ,'M','Plus',12.2314],
['SP','Max' ,'M','Minus',-2.2314],
['CH','Sam' ,'M','Plus',453.7685],
['CH','Sam' ,'M','Minus',-53.7685],
['CH','Sara','F','Plus',777.666],
['CH','Sara','F','Minus',-77.666],
['DE','Hans','M','Plus',345.088],
['DE','Hans','M','Minus',-45.088],
['DE','Paul','M','Plus',222.455],
['DE','Paul','M','Minus',-22.455]]
for i, TestDataRow in enumerate(TestData):
for j, TestDataItem in enumerate(TestDataRow):
Sheet1.Cells(i+2,j+4).Value = TestDataItem
cl1 = Sheet1.Cells(2,4)
cl2 = Sheet1.Cells(2+len(TestData)-1,4+len(TestData[0])-1)
PivotSourceRange = Sheet1.Range(cl1,cl2)
PivotSourceRange.Select()
wb.Worksheets.Add()
Sheet2 = wb.Worksheets("Sheet2")
cl3=Sheet2.Cells(4,1)
PivotTargetRange= Sheet2.Range(cl3,cl3)
PivotTableName = 'ReportPivotTable'
PivotCache = wb.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=PivotSourceRange, Version=win32c.xlPivotTableVersion14)
PivotTable = PivotCache.CreatePivotTable(TableDestination=PivotTargetRange, TableName=PivotTableName, DefaultVersion=win32c.xlPivotTableVersion14)
PivotTable.PivotFields('Name').Orientation = win32c.xlRowField
PivotTable.PivotFields('Country').Orientation = win32c.xlPageField
PivotTable.PivotFields('Country').CurrentPage = 'SP'
PivotTable.PivotFields('Gender').Orientation = win32c.xlColumnField
PivotTable.PivotFields('Sign').Orientation = win32c.xlColumnField
DataField = PivotTable.AddDataField(PivotTable.PivotFields('Amount'))
Excel.Visible = 1
wb.SaveAs('ranges_and_offsets.xlsx')
Excel.Application.Quit()
This generates a pivot table in excel and sets the Country Filter to SP. I know adding the following line will enable the multi selection option.
PivotTable.PivotFields('Country').EnableMultiplePageItems = True
At this point, I'm stuck. I would like to find a way to set Country to both SP and DE. I feel like the correct way to do this is to switch .CurrentPage to .CurrentPageList
However, I can't seem to get .CurrentPageList to work
Any help would be highly appreciated!
this maybe too late for this post, but the way I solved this was creating two loops
PivotTable.PivotFields(target_column).Position = some_position
PivotTable.PivotFields(target_column).EnableMultiplePageItems = True
for item in show_values:
PivotTable.PivotFields(target_column).PivotItems(item).Visible = True
for item in excl_values:
PivotTable.PivotFields(target_column).PivotItems(item).Visible = False
I hope it helps!
I'm trying to add a calculated column into this pivot table that is being generated via a python script with import win32com.client.
Code is posted below that is generating the pivot table. I'm not sure how to add a column. In VBA it would be wb.PivotTable.CalculatedField.Add but that didn't work (at least the syntax I tried).
I'm trying to calculate [OoCUnits] / [GrossUnits]
#Make Pivot version with four weeks data
Excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
win32c = win32com.client.constants
wb = Excel.Workbooks.Open(filename)
ws3 = wb.Worksheets('Dataset')
cl1 = ws3.Cells(1,1)
cl2 = ws3.Cells(max_row,max_col)
PivotSourceRange = ws3.Range(cl1,cl2)
ws3.Activate()
PivotSourceRange.Select()
wb.Sheets.Add (After=wb.Sheets(3))
ws4 = wb.Worksheets(4)
ws4.Name = 'Pivot'
cl3 = ws4.Cells(4,1)
PivotTargetRange = ws4.Range(cl3,cl3)
PivotTableName = 'OoCPivot'
#Make Pivot Table
PivotCache = wb.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=PivotSourceRange, Version=win32c.xlPivotTableVersion14)
PivotTable = PivotCache.CreatePivotTable(TableDestination=PivotTargetRange, TableName=PivotTableName, DefaultVersion=win32c.xlPivotTableVersion14)
PivotTable.PivotFields('Product Name').Orientation = win32c.xlRowField
PivotTable.PivotFields('Product Name').Position = 1
PivotTable.PivotFields('Customer Number').Orientation = win32c.xlPageField
PivotTable.PivotFields('Customer Number').Position = 1
PivotTable.PivotFields('Customer Name').Orientation = win32c.xlPageField
PivotTable.PivotFields('Customer Name').Position = 2
PivotTable.PivotFields('Week Ending Date').Orientation = win32c.xlColumnField
PivotTable.PivotFields('Week Ending Date').Position = 1
DataField = PivotTable.AddDataField(PivotTable.PivotFields('GrossUnits'))
DataField.NumberFormat = '#0.00'
DataField = PivotTable.AddDataField(PivotTable.PivotFields('OoCUnits'))
DataField.NumberFormat = '#0.00'
I'm inserting the values with the DataField. The script is not presenting any issues as is.
EDIT: The exact code I implemented to solve. The last two lines are just formatting. I'm including in case it helps someone else.
CalcField = PivotTable.CalculatedFields().Add('OoC Unit %','= OoCUnits / GrossUnits')
DataField = PivotTable.AddDataField(PivotTable.PivotFields('OoC Unit %'))
DataField.NumberFormat = '#%'
PivotTable.DisplayErrorString = True
Actually, the method is PivotTable.CalculatedFields().Add() according to docs. Consider placing below at bottom:
CalcField = PivotTable.CalculatedFields().Add("OC_GrossPct", "= OoCUnits / GrossUnits")
PivotTable.PivotFields("OC_GrossPct").Orientation = win32c.xlDataField
I need to know how to connect Excel with SAP using RFC. I have not managed to import any SAP data to Excel using the codes found so far.
I would like to be able to import data from any known transaction (e.g. a bill of materials from transaction CO03). From this I would try to understand how to extract other type of tables.
My goal is to be able to import any SAP data on a Excel spreadsheet using RFC. That would be a good start.
Do I need a special SAP account? How to verify my account is enabled to perform this type of tasks?
It is not possible to call any standard transaction remotely as most of them are legacy-like and doesn't return anything directly.
There are couple of ways to fetch data from any transaction but they are out of the scope of this question. The most practical way of retrieveing data from SAP to Excel is to find proper BAPI or remote-enabled FM, (including writing own wrapper FM) and this is the way I gonna describe here.
You don't need special account, you just need to have proper authorizations for RFC-calls, which mainly comprise of S_RFC authorization object
If you use BAPI, you can omit this point. If you created own wrapper, then you have to assure it is remote-enabled.
And then you can call your FM in VBA code and return results to Excel book. Here is the sample code:
' Logging in
Dim retcd As Boolean
Dim SilentLogon As Boolean
Set LogonControl = CreateObject("SAP.LogonControl.1")
Set objBAPIControl = CreateObject("SAP.Functions")
Set R3Connection = LogonControl.NewConnection
R3Connection.Client = "700"
R3Connection.ApplicationServer = "server_address"
R3Connection.Language = "EN"
R3Connection.User = "sap_user"
R3Connection.Password = "sap_pass"
R3Connection.System = "system_id"
R3Connection.SystemNumber = "sys_num"
R3Connection.UseSAPLogonIni = False
retcd = R3Connection.Logon(0, SilentLogon)
If retcd <> True Then MsgBox "Logon failed": Exit Sub
' Declaring FM interface
objBAPIControl.Connection = R3Connection
Set objgetaddress = objBAPIControl.Add("ZNM_GET_EMPLOYEE_DETAILS")
Set objkunnr = objgetaddress.Tables("ET_KUNNR")
Set objaddress = objgetaddress.Tables("ET_CUST_LIST")
' Filling select-options values table from sheet
Dim sht As Worksheet
Set sht = ThisWorkbook.ActiveSheet
If sht.Cells(6, 2).Value <> " " Then
objkunnr.Rows.Add
objkunnr.Value(1, "SIGN") = sht.Cells(6, 2).Value
objkunnr.Value(1, "OPTION") = sht.Cells(6, 3).Value
objkunnr.Value(1, "LOW") = sht.Cells(6, 4).Value
objkunnr.Value(1, "HIGH") = sht.Cells(6, 5).Value
R3Connection.Logoff
P.S. For all this to work in your VBA project you should add references to SAP ActiveX controls, which are located in %ProgramFiles%\SAP\FronEnd\SAPgui directory:
wdtaocxU.ocx
wdtfuncU.ocx
wdtlogU.ocx
wdobapiU.ocx
So references list of your VBA project should look like this
Additionally to Excel solution you may try this open source MS Access application I created long time ago and used many times:
https://blogs.sap.com/2013/08/16/read-data-from-sap-tables-into-ms-access-2003-database/
I am trying to style some cells, I'd like to use the standard "Hyperlink" Style, but I am unable to find it.
here is my best guess code, but the Workbook does not contain a style other than "standard"
var hLinkStyle = (from s in dataSheet.Workbook.Styles.NamedStyles where s.Name == "Hyperlink" select s).FirstOrDefault();
hyperlinkCell.StyleName = hLinkStyle.Name;
Try to create a named style and set it to the cell as follows:
// string link = "your link".
// worksheet is your worksheet reference.
var namedStyle = worksheet.Workbook.Styles.CreateNamedStyle("HyperLink");
namedStyle.Style.Font.UnderLine = true;
namedStyle.Style.Font.Color.SetColor(Color.Blue);
cell.Hyperlink = new ExcelHyperLink(link);
cell.StyleName = namedStyle.Name;
cell.Value = link;
Please refer to EPP example for detail.