converting vba to perl without win32::ole

M

matt

I am currently trying to convert a vba macro to perl. The vba macros
are basically find and replaces on txt files. The problem is that there
are roughly 25000 find and replaces and they are setup to run in a
sequential order, meaning that they search for a string and if the
string is found then it will find and replace from that point on until
EOF. Once it reaches the EOF it will then reset to the start of the txt
file and continues on to the next find and replace. How can I
accomplish this type of parsing with perl. I am trying to get the vba
code out of microsoft word so I do not want to use the win32::eek:le for
this conversion. Here is a snippet of the VBA and converted perl code.
Thanks for any help in advance.

<SNIP>
VBA code:

Set variable = New variable_Class
If variable.FindText("<R [,;)]") = True Then
Selection.Collapse wdCollapseEnd
If variable.FindText("<R [,;)]") = True Then
Selection.Collapse wdCollapseEnd
If variable.FindText("<R [,;)]") = True Then
Selection.Collapse wdCollapseEnd
If variable.FindText("[0-9]{1,} [0-9]{1,} [0-9]") =
True Then
Selection.HomeKey wdStory
variable.FindandReplace "(^13+pg,[0-9]{1,}^13)(+l)
", " \2\1"
Call Subroutine
End If
End If
End If
End If


Perl converted code:

if ($_=~/<R [,;)]/){
#Selection.Collapse wdCollapseEnd <==not sure how to convert
this to perl
if ($_=~/<R [,;)]/){
#Selection.Collapse wdCollapseEnd <==not sure how to convert
this to perl
if ($_=~/<R [,;)]/){
#Selection.Collapse wdCollapseEnd <==not sure how to convert
this to perl
if ($_=~/[0-9]{1,} [0-9]{1,} [0-9]/){
#Selection.HomeKey wdStory <==not sure how to convert this
to perl
$_=~s/(\n\+pg,[0-9]{1,}\n)(\+l)/ $2$1/g;
&Subroutine;
}
}
}
}
 
D

Dave

matt said:
I am currently trying to convert a vba macro to perl. The vba macros
are basically find and replaces on txt files. The problem is that there
are roughly 25000 find and replaces and they are setup to run in a
sequential order, meaning that they search for a string and if the
string is found then it will find and replace from that point on until
EOF. Once it reaches the EOF it will then reset to the start of the txt
file and continues on to the next find and replace. How can I
accomplish this type of parsing with perl. I am trying to get the vba
code out of microsoft word so I do not want to use the win32::eek:le for
this conversion. Here is a snippet of the VBA and converted perl code.
Thanks for any help in advance.

<SNIP>
VBA code:

Set variable = New variable_Class
If variable.FindText("<R [,;)]") = True Then
Selection.Collapse wdCollapseEnd
If variable.FindText("<R [,;)]") = True Then
Selection.Collapse wdCollapseEnd
If variable.FindText("<R [,;)]") = True Then
Selection.Collapse wdCollapseEnd
If variable.FindText("[0-9]{1,} [0-9]{1,} [0-9]") =
True Then
Selection.HomeKey wdStory
variable.FindandReplace "(^13+pg,[0-9]{1,}^13)(+l)
", " \2\1"
Call Subroutine
End If
End If
End If
End If


Perl converted code:

if ($_=~/<R [,;)]/){
#Selection.Collapse wdCollapseEnd <==not sure how to convert
this to perl
if ($_=~/<R [,;)]/){
#Selection.Collapse wdCollapseEnd <==not sure how to convert
this to perl
if ($_=~/<R [,;)]/){
#Selection.Collapse wdCollapseEnd <==not sure how to convert
this to perl
if ($_=~/[0-9]{1,} [0-9]{1,} [0-9]/){
#Selection.HomeKey wdStory <==not sure how to convert this
to perl
$_=~s/(\n\+pg,[0-9]{1,}\n)(\+l)/ $2$1/g;
&Subroutine;
}
}
}
}

OK this code is just covering for the lack of a true Regular Expression
engine in VBA. The Selection.Collapse bit is just saying 'start the next
part of the search from the end of the last succesful one'.

It is equivalent to:

if ($_ =~ /<R [,;)].*<R [,;)].*<R [,;)].*[0-9]+ [0-9]+ [0-9]/) {
$_ =~ s/(\n\+pg,[0-9]+\n)(\+l)/ $2$1/g;
&Subroutine;
}

(untested)

If this is not enough to put you on the right trial post again for more
clarification.

I'm not sure why you refer to win32::eek:le, if you want to parse the VBA code
using perl to automatically convert it, you can save it as a text file,
(.vbs is just a plain text file).
 
M

matt

I'm not sure why you refer to win32::eek:le, if you want to parse the VBA code
using perl to automatically convert it, you can save it as a text file,
(.vbs is just a plain text file).

Only reason I mentioned win32::eek:le was because I didn't want someone to
suggest that I use the ActiveState Perl Dev Kit and run the VBScript
converter tool. My main goal is to remove the memory hog Microsoft
products.

One other question I have is: "Will the global substitution after the
if stmt replace until the EOF or will it replace for the entire file?"
if ($_ =~ /<R [,;)].*<R [,;)].*<R [,;)].*[0-9]+ [0-9]+ [0-9]/) {
$_ =~ s/(\n\+pg,[0-9]+\n)(\+l)/ $2$1/g;
&Subroutine;
}
 
D

Dave

matt said:
I'm not sure why you refer to win32::eek:le, if you want to parse the VBA
code
using perl to automatically convert it, you can save it as a text file,
(.vbs is just a plain text file).

Only reason I mentioned win32::eek:le was because I didn't want someone to
suggest that I use the ActiveState Perl Dev Kit and run the VBScript
converter tool. My main goal is to remove the memory hog Microsoft
products.

One other question I have is: "Will the global substitution after the
if stmt replace until the EOF or will it replace for the entire file?"
if ($_ =~ /<R [,;)].*<R [,;)].*<R [,;)].*[0-9]+ [0-9]+ [0-9]/) {
$_ =~ s/(\n\+pg,[0-9]+\n)(\+l)/ $2$1/g;
&Subroutine;
}

It will replace for the whole file, as does the original VBA code, I think -
Selection.HomeKey wdStory
resets to the beginning of the file.

However I'm not sure now that your searching and your Selection operations
are happening on the same thing...

Notably findText and FindandReplace are not standard methods in VBA. What
libraries are you using? What is Variable_class?

I think you need to provide fuller information.
 
M

matt

It will replace for the whole file, as does the original VBA code, I think -
Selection.HomeKey wdStory
resets to the beginning of the file.
Selection.HomeKey wdStory does reset to the beginning of the file and
the VBA code does replace for the whole file
However I'm not sure now that your searching and your Selection operations
are happening on the same thing...

Notably findText and FindandReplace are not standard methods in VBA. What
libraries are you using? What is Variable_class?
Sorry about the lack of information(definitely don't know VBA very
well, I am trying to fix someone elses mess) findText will search for a
string that is passed in and will highlight to the selection object the
next occurance. FindandReplace will search through the document for
the passed in string and replace it with the replacement string (uses
..Execute Replace:=wdReplaceAll)

How would I search for a string and once found do find and replaces
from that point on until EOF in perl?

Thanks for your help so far
 
D

Dave

matt said:
Selection.HomeKey wdStory does reset to the beginning of the file and
the VBA code does replace for the whole file

Sorry about the lack of information(definitely don't know VBA very
well, I am trying to fix someone elses mess) findText will search for a
string that is passed in and will highlight to the selection object the
next occurance. FindandReplace will search through the document for
the passed in string and replace it with the replacement string (uses
.Execute Replace:=wdReplaceAll)

How would I search for a string and once found do find and replaces
from that point on until EOF in perl?

Thanks for your help so far

You are probably looking for the \G modifier:

if ($_ =~ /<R [,;)].*<R [,;)].*<R [,;)].*[0-9]+ [0-9]+ [0-9]/) {
$_ =~ s/\G(\n\+pg,[0-9]+\n)(\+l)/ $2$1/g;
&Subroutine;
}

(untested)
 
D

Dave

You are probably looking for the \G modifier:
if ($_ =~ /<R [,;)].*<R [,;)].*<R [,;)].*[0-9]+ [0-9]+ [0-9]/) {
$_ =~ s/\G(\n\+pg,[0-9]+\n)(\+l)/ $2$1/g;
&Subroutine;
}

(untested)

No, please ignore this I misunderstood the /G anchor.

This should work :

if ($_ =~ /<R [,;)].*<R [,;)].*<R [,;)].*[0-9]+ [0-9]+ [0-9]/) {
# Use lookbehind assertion and loop to make global
1 while ($_ =~ s/(?<=<R [,;)].*<R [,;)].*<R [,;)].*[0-9]+ [0-9]+
[0-9].*)(\n\+pg,[0-9]+\n)(\+l)/ $2$1/;)
&Subroutine;
}

(untested)

You might get away with the /g modifier rather than the while loop - try it
and see. I can't quite work out all the consequences of the multiple .* in
the look-behind assertion on the behavior of /g, although it might be OK. If
it is slow there may be ways to optimise it (using .*? may help).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top