Tenjou 0 Posted April 3, 2023 Hi first sry for my bad english :-D We have a program to send emails, which is developed in Delphi, but it has an issue with Word Document. After doing some reasech, i found Python4Delphi, and i thought maybe it can be solved our problem. And Python do it very well but only one time. I create a VLC Form which creates a Python.Engine, then the Word Document read out, i get me the Values into Delphi. After that the Values will be searched in our Database, and goes back to Python and Write the Right Values into the matching places. Then the Word Document will be saved and converted to PDF. Like i said, one Time it works very well, but if i add another Dokument to the Tool i get a Error message TypeError: 'NoneType' object is not callable' pythonScript.add('import docx # arbeiten mit docx-Dateien'); pythonScript.add('import re # reguläre Ausdrücke'); pythonScript.add('from docx.shared import Pt'); pythonScript.add('from docx import Document'); pythonScript.add('class TProperties:'); pythonScript.add(' def __init__(Self, DelphiVar):'); pythonScript.add(' Self.__DelphiVar__ = DelphiVar'); pythonScript.add(' def __getattr__(Self, Key):'); pythonScript.add(' return Self.__dict__['+#39+'__DelphiVar__'+#39+'].Value[Key]'); pythonScript.add(' def __setattr__(Self, Key, Value):'); pythonScript.add(' if Key == "__DelphiVar__":'); pythonScript.add(' Self.__dict__['+#39+'__DelphiVar__'+#39+'] = Value'); pythonScript.add(' else:'); pythonScript.add(' Self.__DelphiVar__.Value[Key] = Value'); pythonScript.add(' Self.__DelphiVar__.Value = Self.__DelphiVar__.Value'); pythonScript.add(' def __repr__(Self):'); pythonScript.add(' return str(Self.__DelphiVar__.Value)'); pythonScript.add(' def __str__(Self):'); pythonScript.add(' return str(Self.__DelphiVar__.Value)'); pythonScript.add('def find_search_terms(doc_path):'); pythonScript.add(' try:'); pythonScript.add(' #Open the docx file'); pythonScript.add(' document = docx.Document(doc_path)'); pythonScript.add(' # Regular expression to use for the search'); pythonScript.add(' pattern = re.compile(r'+#39+'«(.*?)»'+#39+')'); pythonScript.add(' # List to store the found search terms'); pythonScript.add(' found_terms = []'); pythonScript.add(' # Iterate through the paragraphs in the document'); pythonScript.add(' for paragraph in document.paragraphs:'); pythonScript.add(' for match in pattern.finditer(paragraph.text):'); pythonScript.add(' found_terms.append(match.group(1))'); pythonScript.add(' # Iterate through the tables in the document'); pythonScript.add(' for table in document.tables:'); pythonScript.add(' # Iterate through the rows in the table'); pythonScript.add(' for row in table.rows:'); pythonScript.add(' # Iterate through the cells in the row'); pythonScript.add(' for cell in row.cells:'); pythonScript.add(' #Check if the search term is in the cell text'); pythonScript.add(' for match in pattern.finditer(cell.text):'); pythonScript.add(' found_terms.append(match.group(1))'); pythonScript.add(' return found_terms'); pythonScript.add(' except docx.opc.exceptions.PackageNotFoundError:'); pythonScript.add(' print("The file could not be found. Please check the file path and try again.")'); pythonScript.add(' except docx.opc.exceptions.PackageLoadError:'); pythonScript.add(' print("There was an error reading the file. It may be damaged or have an unsupported format.")'); pythonScript.add('print("Inhalt Array: vor dem Props")'); pythonScript.add('Props = TProperties( Properties )'); pythonScript.add('print("Inhalt Array: Nach dem Props")'); pythonScript.add('pfad = r'+#39+docPath+#39); pythonScript.add('search_terms = find_search_terms(pfad)'); pythonScript.add('#delete duplicates'); pythonScript.add('my_set = set(search_terms)'); pythonScript.add('search_terms = list(my_set)'); pythonScript.add('for value in search_terms:'); pythonScript.add(' Props.TestDict.append(value)'); pythonScript.add('print("Inhalt Array: "+Props.TestDict[0])'); MaskFPUExceptions(true); PythonEngine1.ExecStrings(pythonScript); MaskFPUExceptions(false); i hope someone can help me with that problem Share this post Link to post
KoRiF 1 Posted April 5, 2023 (edited) from what I see here, your problem lies in the plane of python and not Delphi Your error says that the ElementNamespaceClassLookup field of the etree object has not been properly initialized why it happened is hard to say based on the fact that the problem occurs at the time of import, we can assume a problem with the version of the library I'm sorry, I didn't carefully read the condition under which your problem occurs. there could also probably be a problem with initializing some Python object that is logically meant to be a singleton, a resource access violation (which implies exclusive ownership) or something like that try also rewriting the code so that imports are called from Delphi only once to change your logic You can learn how to pass variables and events between Python and Delphi in the webinar examples. P.S. IMHO debugging problems like this is the Achilles heel of nested Python (Python4Delphi is great but it may be tricky to debug python issues) P.P.S. it seems to me that your task could be solved by the "classic" means of Delphi, although my knowledge may be outdated https://blogs.embarcadero.com/create-word-docs-using-the-direct-office-component-in-delphi-on-windows/ http://delphiprogrammingdiary.blogspot.com/2018/09/ms-word-automation-in-delphi.html P.P.P.S. this is definitely a matter of taste but I would store the multiline python script in an external py file (and load it with a-la TStringList.LoadFromFile()) or at least using TMemo.Lines.Text make it available in dfm file and separate editor window. It would make life much easier Edited April 5, 2023 by KoRiF 1 Share this post Link to post
David Heffernan 2353 Posted April 6, 2023 Yeah. Don't write code like this. Put the code in a text file and link it as a resource. And then debug the code in Python. Once you've debugged it, run it from Delphi. Share this post Link to post
Tenjou 0 Posted April 6, 2023 Hi, I solved the problem, unfortunately destroying and recreating the engine wasn't enough. Unfortunately, I also have to unload the DLL files for each process. Now it is working ty for you help PS: Need to hardcode the entire Script because have noch chance to upload the Script on our Customers System. PPS: Delphi needs to work with Office Word Appl. if we have to manipulate a word Doc, and thats a issue for our Customer, and Python dont need the Word Appl. Share this post Link to post
David Heffernan 2353 Posted April 6, 2023 42 minutes ago, Tenjou said: PS: Need to hardcode the entire Script because have noch chance to upload the Script on our Customers System. Nobody says anything about uploading it to your customers system. You can store it as a resource linked to your executable to make it easier to develop and work with. 43 minutes ago, Tenjou said: PPS: Delphi needs to work with Office Word Appl. if we have to manipulate a word Doc, and thats a issue for our Customer, and Python dont need the Word Appl. There are good libraries for this in other languages, e.g. .net. Are there really no good Delphi libraries for this? Seems kinda wild that your customer is happy for you to splat an entire Python distro with third party modules (python-docx) onto their system, but OMG you can't save a text file with a script in. But yeah, go ahead and execute any code found in your executable, just don't save it to my disk. Doesn't sound very rational. Share this post Link to post
Tenjou 0 Posted April 6, 2023 sry that my requirements annoy you! ty for your help Share this post Link to post