AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Embedded Windows Scripting (VBScript & JScript) and COM
Goto page Previous  1, 2, 3 ... , 11, 12, 13  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
ramin
Guest





PostPosted: Fri Apr 10, 2009 8:20 pm    Post subject: Reply with quote

Thank you so much erictheturtle. Your corrections give me some guidelines for the continuation of the project, which is basically to implement the following perl script:

Code:
#! /usr/bin/perl

# exportCoursePDF.pl
# Generates PDF files from a list of PPT files
#
# To use:
#
# 1. Save this Perl script to a desired location.  For instance, C:\course_resources\exportCoursePDF.pl
#
# 2. Install Perl.  You can do this here:  http://www.activestate.com/activeperl/
#      You can check to ensure you have a Perl installation by entering
#         >perl -v
#     in a command window.
#
# 3. Open a command window and navigate to the directory containing the PPT files
#
# 4. Call this Perl script with the input argument *.ppt (or whichever PPT files you would like to generate).  You may have to give the absolute path to the Perl script:
#
#       >perl C:\course_resoures\exportCoursePDF.pl *.ppt
#
#


#use Microsoft Office Object Libraries
use Win32::OLE;
use Win32::OLE::Const "Microsoft PowerPoint 12.0 Object Library";
use Win32::OLE::Const "Microsoft Office 12.0 Object Library"; #mso constants

#use libraries for obtaining current working directory
use Cwd;
use Cwd 'abs_path';


# Process the input arguments
foreach $arg (@ARGV) {

    # Expand into a list if necessary (e.g. if the filename contains a *)
    @files = glob($arg);

    foreach $file (@files) {

   export_doc($file);

    }

}


sub export_doc {

    my $file = shift @_;
    chomp $file;
   
   #Microsoft office constant values
   my $msTrue = -1;
   my $msFalse = 0;
   
   #swap .ppt with .pdf for output file name
   my $abs_path = abs_path($file);
   $pdfFile = $abs_path;
   $pdfFile =~ s/\.ppt/\.pdf/g;
   
   print "\nExporting " . $pdfFile . "...\n ";
   
    # Open connection to Powerpoint
    # Note: Use second argument of \&Quit for quit callback
    $ppt = Win32::OLE->new('PowerPoint.Application')
   || die("Cannot open connection to PowerPoint.");

    # Load the PowerPoint Contants from the Type Library
    $Const = Win32::OLE::Const->Load($ppt);
   
   # Constants for printing:
   $formatType = $Const->{ppFixedFormatTypePDF};
   $intent = $Const->{ppFixedFormatIntentPrint};
   $frameSlides = $msFalse;
   $slideOrder = $Const->{ppPrintHandoutVerticalFirst};
   $printWhat = $Const->{ppPrintOutputNotesPages};
   $printHidden = $msTrue;
   
    # Attempt to open the presentation
    my $pres = $ppt->Presentations->Open($abs_path,0,0,0) || die Win32::OLE->LastError();
   
   #Export
   $pres->ExportAsFixedFormat($pdfFile,$formatType, $intent, $frameSlides, $slideOrder,$printWhat, $printHidden, $pres->PrintOptions->Ranges->Add(1,1), $Const->{ppPrintAll}, '', 0, 0, 0, 1, 0);


   print "   ===> Done. \n";

    # Quit PPT
    $ppt->Quit;

    # Shutdown COM connection
    undef $ppt;
   
}


It converts the note page view of PPTs to PDF and I want to build the gui around it in AHK. Hopefully, I'm going the right direction! I guess my main challenge is to do the following line with WS_Exec:

Code:

$pres->ExportAsFixedFormat($pdfFile,$formatType, $intent, $frameSlides, $slideOrder,$printWhat, $printHidden, $pres->PrintOptions->Ranges->Add(1,1), $Const->{ppPrintAll}, '', 0, 0, 0, 1, 0);


Any recommendations?
Thanks again!
Back to top
erictheturtle



Joined: 27 Jun 2007
Posts: 90
Location: California

PostPosted: Fri Apr 10, 2009 9:19 pm    Post subject: Reply with quote

Looks like it's a new function for Office 2007. This should help you with the parameters.

http://msdn.microsoft.com/en-us/library/bb231096.aspx

Edit: woops, fixed a memory leak in the code I posted in my previous post.
_________________
-m35
Back to top
View user's profile Send private message
ramin
Guest





PostPosted: Fri Apr 10, 2009 10:26 pm    Post subject: Reply with quote

Thanks! I'm still trying to figure out how to send more than one parameter to a method using WS_Exec. The ExportAsFixedFormat method has 15 parameters and other than the path, they are all static. I already tried this but with no luck:
Code:
Loop, Parse, FileList, |
   {
   StringReplace, pdfPath, A_LoopField, ppt, pdf
   WS_Exec("ppApp.Presentations.Open(""" A_LoopField """)")
   WS_Exec("ppApp.ExportAsFixedFormat(""" pdfPath ",ppFixedFormatTypePDF,ppFixedFormatIntentPrint,msoCFalse,ppPrintHandoutVerticalFirst,ppPrintOutputNotesPages,msoCTrue,,,,False,False,False,True,False"")")
   }
Back to top
erictheturtle



Joined: 27 Jun 2007
Posts: 90
Location: California

PostPosted: Fri Apr 10, 2009 10:38 pm    Post subject: Reply with quote

Not tested, but this, or something very similar might work.

Code:
Loop, Parse, FileList, |
{
   StringReplace, pdfPath, A_LoopField, ppt, pdf
   WS_Exec("Set ppPres = ppApp.Presentations.Open(""" A_LoopField """)")
   sBigCode =
   (
      ppPres.ExportAsFixedFormat("%pdfPath%", ppFixedFormatTypePDF, _
                           ppFixedFormatIntentPrint, msoCFalse, _
                           ppPrintHandoutVerticalFirst, ppPrintOutputNotesPages, _
                           msoCTrue,,,,False, False, False, True, False)
   )
   WS_Exec(sBigCode)
}


Also don't forget to check ErrorLevel for details of what's wrong.
_________________
-m35
Back to top
View user's profile Send private message
ramin
Guest





PostPosted: Fri Apr 17, 2009 7:43 pm    Post subject: Reply with quote

Thanks again erictheturtle. I finally managed to create the tool and make it do what I wanted! I had to go to the Object Browser inside the VB editor and find the constant values for each of the parameter and hard code them in. The loop looks like this now:

Code:
Loop, Parse, FileList, |
   {
      StringReplace, pdfPath, A_LoopField, ppt, pdf
      
      
      openCode =
      (
      Set ppPres = ppApp.Presentations.Open("%A_LoopField%", 0, 0, 0)
      )
      If (!WS_Exec(openCode))
      Msgbox Error in openig the presentations: ErrorLevel
      
      sBigCode =
      (
      ppPres.ExportAsFixedFormat "%pdfPath%", 2, 2, 0, 1, 5, -1, ppPres.PrintOptions.Ranges.Add(1,1), 1,, 0, 0, 0, 1, 0
      )
      
      If (!WS_Exec(sBigCode))
      Msgbox % A_LineFile ":`n" ErrorLevel
   }


I works like a charm. Now I love the capability of running VB code in AHK and got a bunch of other ideas!

Thanks again.[/code]
Back to top
AJohn
Guest





PostPosted: Fri Aug 07, 2009 7:27 pm    Post subject: Reply with quote

Hey erictheturtle - first, thanks a million for your work and time spent at this. Its really an incredible way to extend autohotkey functionality.

I used this thread to set up ahk to run a short .vbs script, and encountered a minor issue - it seems I must wait a few milliseconds between calling WS_Eval and WS_Uninitialize in the following code, or windows gives me a "Autohotkey has encountered a problem and needs to close" error:

complete code:

Code:
#Include ws4ahk.ahk
!a::

zipsource = C:\work\old
zipdest = C:\work\oldtest.zip
 
evalstring = fZip(`"%zipsource%`", `"%zipdest%`")
 
WS_Initialize()

Code =
(
Function fZip(sSourceFolder,sTargetZIPFile)
'This function will add all of the files in a source folder to a ZIP file
'using Windows' native folder ZIP capability.
'Returns an integer 0 if everything went ok.
Dim oShellApp, oFSO, iErr, sErrSource, sErrDescription
Set oShellApp = CreateObject("Shell.Application")
Set oFSO = CreateObject("Scripting.FileSystemObject")
 'The source folder needs to have a \ on the End
 If Right(sSourceFolder,1) <> "\" Then sSourceFolder = sSourceFolder & "\"
On Error Resume Next
  'If a target ZIP exists already, delete it
  If oFSO.FileExists(sTargetZIPFile) Then oFSO.DeleteFile sTargetZIPFile,True
 iErr = Err.Number
On Error GoTo 0
 If iErr <> 0 Then   
  fZip = iErr
  Exit Function
 End If
On Error Resume Next
 'Write the fileheader for a blank zipfile.
 oFSO.OpenTextFile(sTargetZIPFile, 2, True).Write "PK" & Chr(5) & Chr(6) & String(18, Chr(0))
 iErr = Err.Number
On Error GoTo 0
 If iErr <> 0 Then   
  fZip = iErr
  Exit Function
 End If
On Error Resume Next
 'Start copying files into the zip from the source folder.
 oShellApp.NameSpace(sTargetZIPFile).CopyHere oShellApp.NameSpace(sSourceFolder).Items
 iErr = Err.Number
On Error GoTo 0
 If iErr <> 0 Then   
  fZip = iErr
  Exit Function
 End If
  'Because the copying occurs in a separate process, the script will just continue.  Run a DO...LOOP to prevent the function
  'from exiting until the file is finished zipping.
  Do Until oShellApp.NameSpace(sTargetZIPFile).Items.Count = oShellApp.NameSpace(sSourceFolder).Items.Count
   WScript.Sleep 500
  Loop
fZip = 0
End Function
)
WS_Exec(Code)
WS_Eval(ret, evalstring)
Sleep, 1
WS_Uninitialize()

msgbox %ret%

return



The "Sleep, 1" at the bottom has to be there (or a msgbox or something) or I get that error... doing WS_Uninit immediately after WS_Eval crashes it.


Its only a minor thing, and I didnt read the entire thread so Im sorry if this has been pointed out before, thanks again dude you rule!
Back to top
AJohn
Guest





PostPosted: Fri Aug 07, 2009 8:09 pm    Post subject: Reply with quote

So, after more testing I'm not sure exactly what is going on, but when I call the .vbscript this way:

Code:
WS_Exec(fzipCode)
WS_Eval(fzipret, evalstring)
Sleep, 100
WS_Uninitialize()

msgbox %fzipret% | %evalstring%


and when I'm zipping hundreds of image files (500 .jpgs, 10 megs total), it runs the script, starts the zipping (the 'compressing files' dialog pops up - no way to hide that with XP's .zip function) and displays the messagebox while the .zip is being created. Does this mean the loop at the end of the vbscript is running in a different thread than the ahk sub that contains it? The weird thing is that ahk still crashes, but it waits until I close the message box to do it.... I had originally thought it crashed due to uninitializing too quickly but it seems something else is going on. Any ideas?
Back to top
YMP



Joined: 23 Dec 2006
Posts: 329
Location: Russia

PostPosted: Sat Aug 08, 2009 6:16 pm    Post subject: Reply with quote

I've noticed that placing "On Error Resume Next" before the loop prevents the error. In this case the return value is not blank, it shows 0, as expected.

There is also another trick — define evalstring like this:
Code:

evalstring = fZip "%zipsource%", "%zipdest%"

But here the return value still remains blank.
Back to top
View user's profile Send private message
erictheturtle



Joined: 27 Jun 2007
Posts: 90
Location: California

PostPosted: Tue Aug 11, 2009 4:48 am    Post subject: Reply with quote

@AJohn

Looking at your code, I can't quite tell what you are trying to do. It sounds like you want to use Windows Explorer to compress files. I don't understand how opening a binary file and writing a PK header is supposed to do that. Are you trying to zip several jpg files into one file, or each jpg in its own zip file?

Earlier in this thread someone was reporting a similar problem with crashing when WS_Uninitialize() is called. A call to Sleep solved his problem in that case, but it seems you're having another problem.

If you can clarify what you're trying to do, and maybe post another example, I'll see what I can do.

@YMP
Thanks for trying to help AJohn too :)
_________________
-m35
Back to top
View user's profile Send private message
cdjones



Joined: 15 Sep 2009
Posts: 46
Location: Ga, USA

PostPosted: Mon Sep 21, 2009 4:11 am    Post subject: Reply with quote

http://www.autohotkey.com/forum/viewtopic.php?p=297504#297504

Hi guys. I posted this in Need Help, but then realized it ought to be here also.

Can one of you gurus help please.

Thanks
Back to top
View user's profile Send private message
Scratch



Joined: 22 Jan 2009
Posts: 72

PostPosted: Tue Oct 13, 2009 9:32 pm    Post subject: Fooling around with WS4AHK.... Reply with quote

First of all, thank you, thank you, thank you!

WS4AHK is the probably best thing to happen to AHK since the invention of sliced bread and DLLCALL...

I've been toying with ahk for 2 days and I asked myself, do we really need to use WS_Initialize() explicitly in AHK?

What if we incorporate it in the WS_Exec() function and do a little check if WS was already initialized, so that it won't reinitialize at encountering every WS_Exec(VBsnippet) in AHK ? After all a WS_Exec implies that you wan't to have a scripting host initialized, but you don't want to have it initialized over and over again...

Modified WS4AHKExec here:

Code:

WS_Exec(sCode)
{
if NOT WS_Initialized   ; MODIFIED
      WS_Initialize()
   global __WS_iScriptControlObj__, __WS_iScriptErrorObj__
   
   
   IfEqual __WS_iScriptControlObj__,
   {
      Msgbox % "Windows Scripting has not been initialized!`nExiting application."
      ExitApp
   }
   
   ; Run the code
   Critical, On ; For thread safty
   iErr := __WS_IScriptControl_ExecuteStatement(__WS_iScriptControlObj__, sCode)
   If (iErr = "")
   {
      Critical, Off
      ; ErrorLevel has already been set to whatever error occured
      Return False
   }
   Else
   {
      ErrLvl := ErrorLevel ; save ErrorLevel
      blnIsErr := __WS_IsComError("IScriptControl::ExecuteStatement", iErr)
      
      If (ErrorLevel = 0)
         ErrorLevel := ErrLvl ; restore ErrorLevel
      Else
         ErrorLevel := ErrLvl "`n" ErrorLevel ; append ErrorLevel
         
      If (blnIsErr)
      {
         ; Probably an exception. Get the deatils.
         ; TODO: Find out what HRESULT code(s) mean there is an exception.
         ; FIXME: This call destroys whatever ErrorLevel is
         __WS_HandleScriptError()
         Critical, Off
         Return False
      }
      Else ; success
      {
         Critical, Off
         Return True
      }
   }
WS_Initialized := TRUE   ; MODIFIED
}


This will do an implicit WS_Initialize at encountering your first WS_Exec
and remember that the WS was initialized..

Finally, WS_Initialized is reset when WS_Uninitialized is called:

Code:

WS_Uninitialize()
{
   global __WS_iScriptControlObj__, __WS_iScriptErrorObj__
   
   If __WS_iScriptErrorObj__ is Integer
      If (__WS_iScriptErrorObj__ <> 0)
         __WS_IUnknown_Release(__WS_iScriptErrorObj__)
   
   If __WS_iScriptControlObj__ is Integer
      If (__WS_iScriptControlObj__ <> 0)
         __WS_IUnknown_Release(__WS_iScriptControlObj__)
   
   ErrLvl := ErrorLevel ; save ErrorLevel
   DllCall("ole32\CoUninitialize")
   ErrorLevel := ErrLvl ; restore ErrorLevel
   
   __WS_iScriptControlObj__ := ""
   __WS_iScriptErrorObj__   := ""
WS_Initialized := FALSE   ; MODIFIED
}


A bit quickndirty, but it seems to work...

I think your scriping client is such a valuable extension to AHK that it deserves to be incorporated as a function in AHK itselve, for instance as a block like:

Code:

Ahkvar = Hello World
[WSEXEC]
msgbox "%Ahkvar%"
[/WSEXEC]


Note that special care has to be taken by AHK to evaluate %Ahkvar% first before actually passing control to the scripting host, the current solution is to assign the vbscript to a ahkvariable first and then execute the ahkvariable:

Code:

Ws_Initialize()
Ahkvar = Hello World
vbscript =
(
msgbox "%Ahkvar%"
)
WS_Exec(vbscript)


It works, but a WS start/end block looks much cleaner and could potentially be
used as common placeholders for other future AHK scriptingclients for perl/python etc, like:

Code:

...ahkcode
...ahkcode
...some more
[PYTHON]         ; Block of inline code, using HTML  style
put your python code here....
some more...
[/PYTHON]


Anyway, I am really pleased with the way you extended the functionallity of AHK, here is a little testscript I made, demonstrating how WS4AHK can be a tool to prevent circular reference errors in excel when using iterations in cells.

Code:

A1 = 1       ; AHK Vars to be copied to Excel Cells
A2 = =A1*2
A3 = =A2*3
;
;
startexcel =
(
Dim Excel
Set Excel = CreateObject ("excel.application")
excel.visible = True
)
WS_Exec(startexcel)
;
;
AddWorkbookSheet =
(
Dim workbook
set workbook = excel.workbooks.add
Dim worksheet
set worksheet = excel.Sheets(1) 'The first worksheet
)
WS_Exec(AddWorkbookSheet)
;
;
;
CopyAHKvars2XL =
(
Worksheet.Cells(1, 1).Value = "%A1%"
Worksheet.Cells(2, 1).Value = "%A2%"
Worksheet.Cells(3, 1).Value = "%A3%"
)
WS_Exec(CopyAHKvars2XL)
;
;
;
; Do some math operations and have the cells outputresult returned to the cells input,
; (this would normally cause a circular reference error in Excel, but we can bypass it nicely by reading/writing from AHK using WS_Eval)
;
loop 10
{
WS_Eval(multiplier, "Worksheet.Cells(2, 1).Value")
pipe_output2input =
(
Worksheet.Cells(1, 1).Value = "%multiplier%"
)
WS_Exec(pipe_output2input)
sleep 500
}
WS_Uninitialize()


Note: There is no WS_Initialize in the script as it relies on the modiefied WS4AHK as posted above, you might want to add a WS_Initialize if running with the original WS4AHK.
Code:
Back to top
View user's profile Send private message
temp01



Joined: 09 Jul 2009
Posts: 120

PostPosted: Tue Oct 13, 2009 10:15 pm    Post subject: Re: Fooling around with WS4AHK.... Reply with quote

Scratch wrote:
This will do an implicit WS_Initialize at encountering your first WS_Exec
and remember that the WS was initialized..
...
A bit quickndirty, but it seems to work...

No, it'll call WS_Initialize() every time because you didn't declare the variable as global or static (static won't work if you want to change it from WS_Uninitialize).

Scratch wrote:
Anyway, I am really pleased with the way you extended the functionallity of AHK, here is a little testscript I made, demonstrating how WS4AHK can be a tool to prevent circular reference errors in excel when using iterations in cells.

You could use COM.ahk and do it directly with AHK (instead of using VBS) or use COM + MSScript Control to execute JS/VBS code.
Back to top
View user's profile Send private message
Scratch



Joined: 22 Jan 2009
Posts: 72

PostPosted: Tue Oct 13, 2009 11:27 pm    Post subject: Reply with quote

That was the quickndirty part Very Happy thx, i'll remember to declare my variables more carefully
Back to top
View user's profile Send private message
ILAN12346
Guest





PostPosted: Thu Nov 19, 2009 7:37 pm    Post subject: Reply with quote

Cool

Code:
#Include ws4ahk.ahk
WS_Initialize()   
gui, add, edit, vsay w200,VBScript in Autohotkey... For the win !!
gui, add, button, gsay,Say
gui, Show
Return

say:
gui, submit, NoHide
Sam(say)
Return

GuiClose:
WS_Uninitialize()
ExitApp
   
Sam(Text)
{
sam=
(
Function Sam(say)
set objVoice = CreateObject ("SAPI.spVoice")
ObjVoice.speak say
 End Function
)
WS_Exec(sam)
Text = sam("%text%")
WS_Eval(Info,Text)

}


MFG Ilan12346
Back to top
ZLogic
Guest





PostPosted: Wed Feb 03, 2010 6:04 pm    Post subject: Excel Search Reply with quote

This is amazing! I have been using this to script things in Excel nicely, but I can't figure out how to search for the range of a given string in an Excel file.

For example, if I want to use ws4ahk to add a certain value 2 cells to the left of a cell with "ABCD" in it, how would I do this? I can reference cells directly, but is there any way to get the address of a cell with a given value in it?

Thanks!
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3 ... , 11, 12, 13  Next
Page 12 of 13

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group