AutoHotkey Community

It is currently May 26th, 2012, 3:57 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 232 posts ]  Go to page Previous  1 ... 9, 10, 11, 12, 13, 14, 15, 16  Next
Author Message
 Post subject:
PostPosted: April 10th, 2009, 8:20 pm 
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!


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: April 10th, 2009, 9:19 pm 
Offline

Joined: June 27th, 2007, 9:07 pm
Posts: 101
Location: California
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 10th, 2009, 10:26 pm 
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"")")
   }


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: April 10th, 2009, 10:38 pm 
Offline

Joined: June 27th, 2007, 9:07 pm
Posts: 101
Location: California
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 17th, 2009, 7:43 pm 
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]


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 7th, 2009, 7:27 pm 
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!


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 7th, 2009, 8:09 pm 
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?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 8th, 2009, 6:16 pm 
Offline

Joined: December 23rd, 2006, 6:02 pm
Posts: 424
Location: Russia
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 11th, 2009, 4:48 am 
Offline

Joined: June 27th, 2007, 9:07 pm
Posts: 101
Location: California
@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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 21st, 2009, 4:11 am 
Offline

Joined: September 15th, 2009, 7:16 pm
Posts: 67
Location: Ga, USA
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


Report this post
Top
 Profile  
Reply with quote  
PostPosted: October 13th, 2009, 9:32 pm 
Offline

Joined: January 22nd, 2009, 3:43 pm
Posts: 84
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:


Report this post
Top
 Profile  
Reply with quote  
PostPosted: October 13th, 2009, 10:15 pm 
Offline

Joined: July 9th, 2009, 9:25 pm
Posts: 120
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 13th, 2009, 11:27 pm 
Offline

Joined: January 22nd, 2009, 3:43 pm
Posts: 84
That was the quickndirty part :D thx, i'll remember to declare my variables more carefully


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 19th, 2009, 7:37 pm 
8)

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


Report this post
Top
  
Reply with quote  
 Post subject: Excel Search
PostPosted: February 3rd, 2010, 6:04 pm 
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!


Report this post
Top
  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 232 posts ]  Go to page Previous  1 ... 9, 10, 11, 12, 13, 14, 15, 16  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: shassen95 and 17 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group