Struggling when transforming VBA code to Python using win32com module

Started by AhmedAl, July 21, 2019, 12:55:15 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

AhmedAl

Hello everyone,


Thanks to everyone contributing to this forum, it's really helping me !

I recently started generating visio files using Python and I have problems with many aspects of visio generation : filling the shapes with specific color, setting the page scale, setting particular font style ....
Can you help me please ?

Right now, I'm stuck with this code (for shapes filling):

objVapp = win32com.client.Dispatch("Visio.Application")
# objVapp = win32com.client.gencache.EnsureDispatch("Visio.Application")
# objVapp.Interactive = False

objVdProc = objVapp.Documents.Add("")

Rect = objVdProc.Pages("PdG").DrawRectangle(1, Coord_y,1 , 1)
Rect.CellsSRC(visSectionObject, visRowXFormOut, visXFormPinX).FormulaU = Coord_x
Rect.CellsSRC(visSectionObject, visRowXFormOut, visXFormWidth).FormulaU = Largeur
Rect.CellsSRC(visSectionObject, visRowXFormOut, visXFormHeight).FormulaU = Hauteur

Rect.Cells("FillPattern").FormulaU = "1"
Rect.Cells("FillForegnd").FormulaU = "THEMEGUARD(RGB(%s,%s,%s))" %(R_Fond, V_Fond, B_Fond)
Rect.Cells("FillBkgnd").FormulaU = "THEMEGUARD(SHADE(FillForegnd,LUMDIFF(THEME(""FillColor""),THEME(""FillColor2""))))"

I have the following error caused by the line just before the last one:
com_error: (-2147352567, 'An exception has occured.', (0, 'Dessin2 - Visio Professionnel', '\n\n#NAME?', None, 0, -2032466907), None)

And even when I'm trying to set a particular font style for the text, I'm getting a similar error, here is my code (error in the 1st line):

Rect.CellsSRC(visSectionCharacter, 0, visCharacterStyle).FormulaU = Carac_Police
Rect.Cells("Char.size").FormulaU = "96 pt"#Taille_Police
Rect.CellsSRC(visSectionCharacter, 0, visCharacterUnderline).FormulaU = True
Rect.CellsSRC(visSectionCharacter, 0, visCharacterColor).FormulaU = "THEMEGUARD(RGB(%s,%s,%s))" %(R_police, V_police, B_police)
Rect.CellsSRC(visSectionCharacter, 0, visCharacterFont).FormulaU = "4" #equivalent to "Arial"

Thanks :)

Yacine

Hello Ahmed,

  Rect.Cells("FillForegnd").FormulaU = "THEMEGUARD(RGB(%s,%s,%s))" %(R_Fond, V_Fond, B_Fond)

The a.m. line worked fine for me. I had of course to define the "xx_Fond" variables first.
You may check whether it's a visio or a python thing, but replacing the formula by one with constants. eg:
  Rect.Cells("FillForegnd").FormulaU = "THEMEGUARD(RGB(100,100,100))"

Cordialement,
Y.
Yacine

AhmedAl

Thanks Yacine, It worked, it looks like I was getting it wrong.

AhmedAl

Hello,

it's me again !

Right now, I'm stuck with this code (inserting jpg images into a shape):

Rect = objVdProc.Pages("PdG").DrawRectangle(1, Coord_y,1 , 1)
Rect.CellsSRC(visSectionObject, visRowXFormOut, visXFormPinX).FormulaU = Coord_x

Rect.CellsSRC(visSectionObject, visRowXFormOut, visXFormWidth).FormulaU = Largeur
Rect.CellsSRC(visSectionObject, visRowXFormOut, visXFormHeight).FormulaU = Hauteur

Rect.Cells("LineColor").FormulaU = "THEMEGUARD(RGB(255,255,255))"
filePath = "C:/Users/aallali/Documents/EDF rédaction de consignes/Logo_edf(1).jpg"
Rect.Import(filePath)

It gave me this error:
  File "C:/Users/aallali/Documents/EDF rédaction de consignes/Notebooks/Génération_Visio_1.0.1.py", line 2652, in <module>
    Rect.Import(filePath)

com_error: (-2147352567, 'An exception has occured.', (0, 'Dessin2 - Visio Professionnel', '\n\nObjet Inappropriate target for this operation.', None, 0, -2032465762), None)

Thanks

vojo

Not an expert but I believe the problem is that Rect defines a rectangle...I dont think you can import a picture into a rectangle.   You may want different kind of object to manage the JPG

Could just turn on Macros and do a copy and paste of an image to see what kind of object is used.

Yacine

I agree with Vojo, that a shape can't be a target for an import operation, although the method is available and documented ... Strange!

2 Methodes to get pictures in Visio:
- choose a page as target. eg activepage.import ...
- create a fill pattern with the image, then apply it to the desired shape.

PS: in VBA in calls to subs the arguments are written without parenthesis. --> activepage.import filePath
Yacine


AhmedAl

Thanks everyone, and thanks metuemre for the last file :)

In fact, I tried only a small step (just importing a random image in empty visio file) and I got com_error as usual, I'm growing frusturated with this ...

This is my code:


import pandas as pd
import sys, win32com.client
import time
from win32com.client import constants

# Visio must be open and I used a "Basic Diagram" template
objVapp = win32com.client.Dispatch("Visio.Application")
# objVapp = win32com.client.gencache.EnsureDispatch("Visio.Application")
# objVapp.Interactive = False

objVdProc = objVapp.Documents.Add("")
objVdProc.Pages(1).Name = "PdG"

objVdProc.Pages(1).Background = False # pas arrière plan donc 1er plan
objVdProc.Pages(1).BackPage = ""

filePath = "C:/Users/myPC/Documents/EDF rédaction de consignes/Logo_edf(1).jpg"

objVapp.ActivePage.Import(filePath)

The error was:

com_error: (-2147352567, 'An exception has occured.', (0, 'Dessin2 - Visio Professionnel',"\n\nAn error has occured. Impossible to keep importing.", None, 0, -2032466039), None)

Please find the image in the attachements

vojo

again...in visio, turn macro recording on and do the paste.   Then look at the resulting macro to see the VBA involved.

As far as python goes, I think you only have to values of VBA objects
I.e. do whatever you want in native Python then use the win32, shape, cell, formula to plug in values to visio.


Nikolay

Visio was designed with VBA in mind, not Python. Not sure why you have chosen python to work with Visio; you get all sorts of problems, starting with configuration, lack of code samples, obscure error messages, lack of intellisense (auto-completion), and finally performance issues.

Paul Herber

Quote from: AhmedAl on July 30, 2019, 09:51:50 AM
The error was:

com_error: (-2147352567, 'An exception has occured.', (0, 'Dessin2 - Visio Professionnel',"\n\nAn error has occured. Impossible to keep importing.", None, 0, -2032466039), None)

Please find the image in the attachements

I can almost foresee the day when computers could be powerful enough to convert -2147352567 and -2032466039 into something more human readable.
(-0x7FFDFFF7 and -0x7924F877 respectively.)
Electronic and Electrical engineering, business and software stencils for Visio -

https://www.paulherber.co.uk/

AhmedAl

@Nikolay because I work on a machine learning project where the output of would be a visio file, and when you say machine learning you say Python & R (but not VBA).

Nikolay

You could use SVG as output maybe? That has much better support in python.
Note that you can open SVG with Visio.

Yacine

Hello Ahmed,
Please find below a code sample that imports an image and makes some basic manipulations with it.
import win32com.client
from win32com.client import constants

def mm2in(x):
    return x / 25.4
def in2mm(x):
    return x * 25.4

# Preparation
template = 'BASICD_M.VSTX' # That's my basic template. Replace by your own.
vApp = win32com.client.Dispatch("Visio.Application")
vApp.Visible = 1
vDoc = vApp.Documents.Add(template)
vPg = vDoc.Pages.Item(1)
vWin = vApp.ActiveWindow

vPg.Name = 'PdG'
vPg.PageSheet.CellsU('DrawingResizeType').FormulaU = '2'

# Importing the image
img_path = 'C:\\Users\\aallali\\Documents\\EDF rédaction de consignes\\Logo_edf(1).jpg'
vImg = vPg.Import(img_path)

# Resizing the image
# Locking the aspect ratio doesn't really lock it when manipulating directly the height and the width by code
img_h = 20
hw_ratio = vImg.CellsU('Height').ResultIU / vImg.CellsU('Width').ResultIU
vImg.CellsU('Height').FormulaU = str(mm2in(img_h))
vImg.CellsU('Width').FormulaU = str(vImg.CellsU('Height').ResultIU  / hw_ratio)

# Positioning the image on the top right corner
margin = 10 # mm

w = in2mm(vPg.PageSheet.CellsU('PageWidth').ResultIU)
h = in2mm(vPg.PageSheet.CellsU('PageHeight').ResultIU)
print(x,y)

vImg.CellsU('LocPinX').FormulaU = 'Width * 1'
vImg.CellsU('LocPinY').FormulaU = 'Height * 1'

x = w - 2 * margin
y = h - 2 * margin
print(x,y)


vImg.CellsU('PinX').FormulaU = str(x) + 'mm'
vImg.CellsU('PinY').FormulaU = str(y) + 'mm'

# duplicate the image
vImg2 = vImg.Duplicate()

# Position it in the left top corner
vImg2.CellsU('LocPinX').FormulaU = 'Width * 0'
x = margin
vImg2.CellsU('PinX').FormulaU = str(x) + 'mm'
vImg2.CellsU('PinY').FormulaU = str(y) + 'mm'

Keep in mind to use the macro recorder to get the syntax of the commands to use.
The supplied code is just a quick demo. Ideally you would re-write it as set of functions to make it re-usable. Have a look at the library I built for myself. It's an IPython notebook though.

Rgds,
Y.
Yacine

AhmedAl

It worked, thank you Yacine.

I started using the macro recorder, so hoepfully I'll get less issues.