In my situation, I translate a python code into nim
# I am cli.py
def checkHeading():
word.Selection.HomeKey(Unit=win32com.client.constants.wdStory,
Extend=win32com.client.constants.wdMove)
do some check on Heading, then display message
def checkPunctation():
word.Selection.HomeKey(Unit=win32com.client.constants.wdStory,
Extend=win32com.client.constants.wdMove)
do some check on punctaion, then display message
def check(fn):
global word
word = win32com.client.gencache.EnsureDispatch("Word.Application")
word.Documents.Open(FileName=fn, ReadOnly=True)
checkHeading()
checkPunctation()
if __name__ == '__main__':
check(r'c:\test.doc')
As you can see, there is global variant word in function check, and this variant can be used in other functions
So I can write the GUI app by using cli.py as module
how ever, in nim even I use
var word {.**global**.} = CreateObject("Word.Application")
in proc check, I still get R:\CheckIt.nim(709, 5) Error: undeclared identifier: 'word'
so is there real python-like global solution except
proc checkHeading() =
word.Selection.HomeKey(...)
do some check on Heading, then display message
proc checkPunctation() =
word.Selection.HomeKey(...)
do some check on punctaion, then display message
proc check(fn):
word.Documents.Open(fn, True)
checkHeading()
checkPunctation()
var word = CreateObject("Word.Application")
-
mratsim
(orginal)
[2018-08-14T19:04:05+02:00]
view original
You forgot the export marker '*':
var Word* = CreateObject("Word.Application")
Also I suggest you use CamelCase for globals.
-
oyster
(orginal)
[2018-08-15T02:37:58+02:00]
view original
thanks, I don't mean to export word from module which is the next step
currently, what I met is that the following command line version cannot be compiled,
R:\CheckIt.nim(709, 5) Error: undeclared identifier: 'word'
because there is no global variant word so checkHeading and checkPunctation can not find it
# I am command line version
proc checkHeading() =
word.Selection.HomeKey(...) # **this line can't find variant word, so the compilation can't succeed**
do some check on Heading, then display message
proc checkPunctation() =
word.Selection.HomeKey(...)
do some check on punctaion, then display message
proc check(fn)=
var word = CreateObject("Word.Application") # how to declare a global `word` as the python version does?
word.Documents.Open(fn, True)
checkHeading()
checkPunctation()
when isMainModule:
check(r"c:\test.doc")
-
jyapayne
(orginal)
[2018-08-15T02:58:42+02:00]
view original
If you move the definition of word to the beginning of the file, it should work fine. Global variables in Nim are simply declared outside of procs, before usage anywhere in the file. So this should work fine:
# I am command line version
var word = CreateObject("Word.Application")
proc checkHeading() =
word.Selection.HomeKey(...) # **this line can't find variant word, so the compilation can't succeed**
do some check on Heading, then display message
proc checkPunctation() =
word.Selection.HomeKey(...)
do some check on punctaion, then display message
proc check(fn)=
word.Documents.Open(fn, True)
checkHeading()
checkPunctation()
when isMainModule:
check(r"c:\test.doc")
The reason it doesn't work if you have it like this:
proc checkHeading() =
word.Selection.HomeKey(...)
do some check on Heading, then display message
proc checkPunctation() =
word.Selection.HomeKey(...)
do some check on punctaion, then display message
proc check(fn):
word.Documents.Open(fn, True)
checkHeading()
checkPunctation()
var word = CreateObject("Word.Application") # needs to be declared first before it is used
is because Nim's parsing semantics are different than Python's. Python's statements are parsed top level first, so as long as a variable is declared somewhere in the file, you can use it within a function. But Nim parses the whole file top to bottom, so if the compiler sees word here:
proc checkHeading() =
word.Selection.HomeKey(...) # **this line can't find variant word, so the compilation can't succeed**
do some check on Heading, then display message
and doesn't have a definition for it, it will throw an error. Alternatively, if you don't want to initialize word at the top of the file, you can declare it at the top like so:
var word: ObjectType # Replace "ObjectType" with the type that CreateObject returns
...
proc check(fn)=
word = CreateObject("Word.Application")
word.Documents.Open(fn, True)
checkHeading()
checkPunctation()