forgedascendant has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, I was hoping that one of you may be able to help me with a problem that I can not figure out. I have VBA code for mathcad interaction as follows:
Dim mathcad, worksheets, sheet Set mathcad = CreateObject("Mathcad.Application") set worksheets = mathcad.Worksheets Set sheet = worksheets.Open("C:\vbscript\testM12.xmcd") sheet.setValue "x",50 sheet.setValue "y",60 sheet.setValue "z",70 sheet.Recalculate MsgBox(sheet.getValue("output1")) MsgBox(sheet.getValue("output2"))
I took this code and used the Win32::OLE module and tranlateded the code into perl and got:
#!/usr/ym/util/perl use Win32::OLE; #Perl "C:/documents and settings/aaron.verellen/desktop/trial2.pl" Win32::OLE->Option(Warn => 2); #use existing instance if mathcad is already running eval {$MC = Win32::OLE->GetActiveObject('Mathcad.Application')}; die "Mathcad not installed" if $@; unless (defined $MC) { $MC = Win32::OLE->new('Mathcad.Application', sub{$_[0]->Quit;}) or die "Unable to start Mathcad"; } #Open specific worksheet my $filePath = 'C:\Documents and Settings\aaron.verellen\Desktop\testM +12.xmcd'; my $WS = $MC->Worksheets; my $S = $WS->Open($filePath); #Set values on the worksheet $S->setValue('x',50); $S->setValue('y',60); $S->setValue('z',70); $S->Recalculate; my $answer1 = $S->getValue('output1'); my $answer2 = $S->getValue('output2'); print "($answer1,$answer2)\n";
Looking at what the mathcad program does, the code does exactly what it is suppose to with one exception...I can not get output1 and output2 back. The getValue does not seem to work. When I run the script I get:

C:\>Perl "C:/documents and settings/aaron.verellen/desktop/trial2.pl"
Win32::OLE(0.1709) error 0xc00000fd
in METHOD/PROPERTYGET "getValue" at C:/documents and settings/aaron.verellen /desktop/trial2.pl line 30

I have tried the Invoke command and get the same error. Does anyone know why this particular methode does not work or have suggestions I could try to get it to work?

Thank you so much,
Aaron

Replies are listed 'Best First'.
Re: WIN32::OLE bridging to MATHCAD
by Anonymous Monk on Apr 18, 2009 at 01:24 UTC
      Ok, so what your telling me is that the getvalue method does not work because of something to do with threads. I went on the forum you pointed me to and posted a request for help there and what I know thus far.

      TO be honest I am not sure what a thread is or how it could be causing a problem. Dispite my ignorance I went to the documentation and found this:

      Win32::OLE->Initialize(COINIT)
      The Initialize() class method can be used to specify an alternative apartment model for the Perl thread. It must be called before the first OLE object is created. If the Win32::OLE::Const module is used then the call to the Initialize() method must be made from a BEGIN block before the first use statement for the Win32::OLE::Const module.

      Valid values for COINIT are:

      Win32::OLE::COINIT_APARTMENTTHREADED - single threaded
      Win32::OLE::COINIT_MULTITHREADED - the default
      Win32::OLE::COINIT_OLEINITIALIZE - single threaded, additional OLE stuff

      COINIT_OLEINITIALIZE is sometimes needed when an OLE object uses additional OLE compound document technologies not available from the normal COM subsystem (for example MAPI.Session seems to require it). Both COINIT_OLEINITIALIZE and COINIT_APARTMENTTHREADED create a hidden top level window and a message queue for the Perl process. This may create problems with other application, because Perl normally doesn't process its message queue. This means programs using synchronous communication between applications (such as DDE initiation), may hang until Perl makes another OLE method call/property access or terminates. This applies to InstallShield setups and many things started to shell associations. Please try to utilize the Win32::OLE->SpinMessageLoop and Win32::OLE->Uninitialize methods if you can not use the default COINIT_MULTITHREADED model.

      So I tried to clear the problem up with the following code:

      #!/usr/ym/util/perl use Win32::OLE; #Perl "C:/documents and settings/aaron.verellen/desktop/trial2.pl" Win32::OLE->Initialize(COINIT_OLEINITIALIZE); Win32::OLE->Option(Warn => 2); #use existing instance if mathcad is already running eval {$MC = Win32::OLE->GetActiveObject('Mathcad.Application')}; die "Mathcad not installed" if $@; unless (defined $MC) { $MC = Win32::OLE->new('Mathcad.Application', sub{$_[0]->Quit;}) or die "Unable to start Mathcad"; } #Open specific worksheet my $filePath = 'C:\Documents and Settings\aaron.verellen\Desktop\testM +12.xmcd'; my $WS = $MC->Worksheets; my $S = $WS->Open($filePath); #Set values on the worksheet $S->setValue('x',50); $S->setValue('y',60); $S->setValue('z',70); $S->Recalculate; my $test = $S->getValue('x'); print "test = $test\n"; my $answer1 = $S->getValue('output1'); my $answer2 = $S->getValue('output2'); print "($answer1,$answer2)\n";
      And I get the same error still. Did I fail to impliment this properly?

      Thanks,
      Aaron

        Ok, so what your telling me is that the getvalue method does not work because of something to do with threads.
        Thats my guess. You need to examine $^E or Win32::OLE->LastError() for a better error message.