Leaderboard
Popular Content
Showing content with the highest reputation on 01/06/2015 in all areas
-
Get All Window's Controls
vergil250493 reacted to jdelaney for a topic
I've wanted to post this for a while. It's a great script to help debug control data....perfect scenario, when you have a 'Button' grouping, and spy tools cannot focus on those controls within the button bounds (groups). I also use it to verify that a given ID is not present more than once...if not, that's how I identify the control in future scripts. Output can be filtered by: 1) Filter by IsVisible 2) Filter by matching class (ex Button, Label, Static) 3) Filter by containing text #include <Array.au3> #include <WinAPI.au3> ConsoleWrite("Make your window active!" & @CRLF) Sleep(5000) GetAllWindowsControls(WinGetHandle("[ACTIVE]")) Func GetAllWindowsControls($hCallersWindow, $bOnlyVisible=Default, $sStringIncludes=Default, $sClass=Default) If Not IsHWnd($hCallersWindow) Then ConsoleWrite("$hCallersWindow must be a handle...provided=[" & $hCallersWindow & "]" & @CRLF) Return False EndIf ; Get all list of controls If $bOnlyVisible = Default Then $bOnlyVisible = False If $sStringIncludes = Default Then $sStringIncludes = "" If $sClass = Default Then $sClass = "" $sClassList = WinGetClassList($hCallersWindow) ; Create array $aClassList = StringSplit($sClassList, @CRLF, 2) ; Sort array _ArraySort($aClassList) _ArrayDelete($aClassList, 0) ; Loop $iCurrentClass = "" $iCurrentCount = 1 $iTotalCounter = 1 If StringLen($sClass)>0 Then For $i = UBound($aClassList)-1 To 0 Step - 1 If $aClassList[$i]<>$sClass Then _ArrayDelete($aClassList,$i) EndIf Next EndIf For $i = 0 To UBound($aClassList) - 1 If $aClassList[$i] = $iCurrentClass Then $iCurrentCount += 1 Else $iCurrentClass = $aClassList[$i] $iCurrentCount = 1 EndIf $hControl = ControlGetHandle($hCallersWindow, "", "[CLASSNN:" & $iCurrentClass & $iCurrentCount & "]") $text = StringRegExpReplace(ControlGetText($hCallersWindow, "", $hControl), "[\n\r]", "{@CRLF}") $aPos = ControlGetPos($hCallersWindow, "", $hControl) $sControlID = _WinAPI_GetDlgCtrlID($hControl) $bIsVisible = ControlCommand($hCallersWindow, "", $hControl, "IsVisible") If $bOnlyVisible And Not $bIsVisible Then $iTotalCounter += 1 ContinueLoop EndIf If StringLen($sStringIncludes) > 0 Then If Not StringInStr($text, $sStringIncludes) Then $iTotalCounter += 1 ContinueLoop EndIf EndIf If IsArray($aPos) Then ConsoleWrite("Func=[GetAllWindowsControls]: ControlCounter=[" & StringFormat("%3s", $iTotalCounter) & "] ControlID=[" & StringFormat("%5s", $sControlID) & "] Handle=[" & StringFormat("%10s", $hControl) & "] ClassNN=[" & StringFormat("%19s", $iCurrentClass & $iCurrentCount) & "] XPos=[" & StringFormat("%4s", $aPos[0]) & "] YPos=[" & StringFormat("%4s", $aPos[1]) & "] Width=[" & StringFormat("%4s", $aPos[2]) & "] Height=[" & StringFormat("%4s", $aPos[3]) & "] IsVisible=[" & $bIsVisible & "] Text=[" & $text & "]." & @CRLF) Else ConsoleWrite("Func=[GetAllWindowsControls]: ControlCounter=[" & StringFormat("%3s", $iTotalCounter) & "] ControlID=[" & StringFormat("%5s", $sControlID) & "] Handle=[" & StringFormat("%10s", $hControl) & "] ClassNN=[" & StringFormat("%19s", $iCurrentClass & $iCurrentCount) & "] XPos=[winclosed] YPos=[winclosed] Width=[winclosed] Height=[winclosed] Text=[" & $text & "]." & @CRLF) EndIf If Not WinExists($hCallersWindow) Then ExitLoop $iTotalCounter += 1 Next EndFunc ;==>GetAllWindowsControls1 point -
March 22, 2015 (NEW udf version in >post #12 . slight enhancement on index and multindex creation) March 21, 2015 (NEW udf version in >post #12 . slight enhancement on index creation) March 15, 2015 (NEW version in >post #9 below. It also allows creation of simple indexes) March 03, 2015 (NEW improved version in >post #7 below) This is a simple udf to manage 1D or 2D arrays by means of SQL query. I hope it can be useful both for simple educational and testing purposes about SQL that also for the management of arrays in general. New version (it makes use of the new "chain insertion" functionality of SQLite as suggested by jchd in post #5) ; save this as ArraySQL.au3 ; V2 #include-once #include <Array.au3> #include <SQLite.au3> #include <SQLite.dll.au3> ; Global Static $g__sSQliteDll = _SQLite_Startup() Global Static $g__hMemDb = _SQLite_Open() Global $g__sSQLiteError = "" ; will contains SQL error messages ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArraySQL ; Description ...: Allows to execute SQL queryes against 1D or 2D arrays ; Syntax.........: _ArraySQL( ByRef $avArray, $sSQL_Query ) ; Parameters ....: $avArray - an 1D or 2D Array to be manage ; $sSQL_Query - a string containing the SQL query to execute against the array ; the passed array is referred as array as table name in the query ; the fields (column(s)) of the array are referred as column0, column1, column2 .... and so on ; ; Return values .: Success: An 1D or 2D array containing data resulting from the execution of the SQL query. ; ; Fillure: an empty string and the @error value is set as following ; 1 - First argument is not an array ; 2 - not a 1D or 2D array ; 3 - SQLite error. In this case the $g__sSQLiteError global variable contains the error description. ; =============================================================================================================================== Func _ArraySQL(ByRef $avArray, $sSQL_Query) Local $aResult, $iRows, $iColumns, $iRval, $iError $g__sSQLiteError = "" __ArrayToSqlTable($avArray) ; clone $avArray to a temporary sql db table (memory resident) ; name of the temp table will be array ; name of the filed(s) will be column0 column1 column2 columnN and so on .... ; If @error Then Return SetError(@error, 0, "") ; something went wrong ; now execute the SQL query $iRval = _SQLite_GetTable2d(-1, $sSQL_Query, $aResult, $iRows, $iColumns) If Not $iRval = $SQLITE_OK Then ; an SQLite error occurred $g__sSQLiteError = _SQLite_ErrMsg() _SQLite_Exec($g__hMemDb, "DROP TABLE array") ; delete the temporary table Return SetError(3, 0, "") Else $g__sSQLiteError = "" _SQLite_Exec($g__hMemDb, "DROP TABLE array") ; delete the temporary table Return SetError(0, 0, $aResult) EndIf EndFunc ;==>_ArraySQL ; ; #INTERNAL USE# ================================================================================================================ ; Name...........: __ArrayToSqlTable ; Description ...: clone $avArray to a temporary SQLite db table (memory resident) ; Syntax.........: __ArrayToSqlTable ( ByRef $avArray) ; Parameters ....: $avArray - Array to clone to the SQLite temporary table ; ; Remarks .......: For Internal Use Only ; =============================================================================================================================== Func __ArrayToSqlTable(ByRef $avArray) ; Pass an array to a temporary SQL table If Not IsArray($avArray) Then Return SetError(1, 0, 0) ; must be an array Local $iDimensions = UBound($avArray, 0) If $iDimensions > 2 Then Return SetError(2, 0, 0) ; must be an 1D or 2D array Local $aAutoItV = StringSplit(@AutoItVersion, ".", 2), $nAutoItVersion = StringFormat("%03i%03i%03i%03i", $aAutoItV[0], $aAutoItV[1], $aAutoItV[2], $aAutoItV[3]) Local $iStep = 10 ; the number of records we want to load in each chain <---- the chain length If $nAutoItVersion < 3003012000 Then $iStep = 1 ; if an older version of AutoIt then do not use the new SQLite "chain insertion" Local $sDBfields = "" ; will hold the names of the fields (column0, column1, column2......) (zero based) Local $vDBvalues = "" ; will hold the values of a field (1, 'aaa', 456) Local $vDBvaluesChain = "" ; will hold the chain of n values (1, 'aaa', 456), (2, 'bbb', 147), ... , (235, 'xyz', 999) Local $iRecords = UBound($avArray, 1) ; total number of rows in the array Local $iLastRecord = $iRecords - 1 Local $iChains = Ceiling($iRecords / $iStep) ; how many chains we will fill? Local $nRemainders = Mod($iRecords, $iStep) ; are there rmainders? (if so the last chain will be only partly full) Local $iFields = 0 ; we suppose an 1D array If $iDimensions = 2 Then ; if is a 2D array instead $iFields = UBound($avArray, 2) - 1 ; number of fields (columns) in the 2D array (zero based) EndIf For $x = 0 To $iFields $sDBfields &= "column" & String($x) & "," Next $sDBfields = StringTrimRight($sDBfields, 1) ; remove the last comma If Not _SQLite_Exec(-1, "CREATE TEMP TABLE array (" & $sDBfields & ");") = $SQLITE_OK Then $g__sSQLiteError = _SQLite_ErrMsg() ; _SQLite_Exec($g__hMemDb, "DROP TABLE array") ; delete the temporary table Return SetError(3, 0, "") Else #cs suggestion by jchd -> http://www.autoitscript.com/forum/topic/166536-manage-arrays-by-means-of-sql/?p=1216694 For maximizing efficiency of table population using INSERT, you can use the "chain insertion" new syntax: insert into mytable (a,b,c) values (1, 'aaa', 456), (2, 'bbb', 147), (3, 'ccc', 258), ... , (235, 'xyz', 999) You need to keep the query string under the size limit (depends on compile-time options) but you can get N-fold (for some value N) improvement on insert speed with that simple trick. #ce If Not $nRemainders Then ; there are no remainder records. ; then we can load all chains (with group of records) ; and we will have no residual records to manage For $x = 0 To $iLastRecord Step $iStep ; we read records in groups of $iStep $vDBvaluesChain = "" For $iRecord = $x To $x + $iStep - 1 $vDBvalues = "" ___BuildRecord($avArray, $iFields, $vDBvalues, $iRecord) ; build data record related to row $iRecord $vDBvaluesChain &= $vDBvalues & "),(" ; build the chain of records Next $vDBvaluesChain = StringTrimRight($vDBvaluesChain, 3) ; remove last "),(" ; insert chain to table ___InsertChain($sDBfields, $vDBvaluesChain) Next ; Else ; if we are here is because there are remainders, so: If $iChains - 1 Then ; if there are more than 1 chain (otherwise if records are less than $istep read only remainders) For $x = 0 To $iLastRecord - $nRemainders Step $iStep $vDBvaluesChain = "" For $iRecord = $x To $x + $iStep - 1 $vDBvalues = "" ___BuildRecord($avArray, $iFields, $vDBvalues, $iRecord) ; build data record related to row $iRecord $vDBvaluesChain &= $vDBvalues & "),(" ; build the chain of records Next $vDBvaluesChain = StringTrimRight($vDBvaluesChain, 3) ; remove last "),(" ___InsertChain($sDBfields, $vDBvaluesChain) Next EndIf ; -- now read remainders ----- $vDBvaluesChain = "" For $iRecord = $iLastRecord - $nRemainders + 1 To $iLastRecord ; Step $iStep $vDBvalues = "" ___BuildRecord($avArray, $iFields, $vDBvalues, $iRecord) ; build data record related to row $iRecord $vDBvaluesChain &= $vDBvalues & "),(" ; build the chain of records Next $vDBvaluesChain = StringTrimRight($vDBvaluesChain, 3) ; remove last "),(" ___InsertChain($sDBfields, $vDBvaluesChain) EndIf EndIf EndFunc ;==>__ArrayToSqlTable Func ___BuildRecord(ByRef $avArray, ByRef $iFields, ByRef $vDBvalues, ByRef $x) For $y = 0 To $iFields Switch $iFields Case 0 ; just 1 field (1D Array) If IsNumber($avArray[$x]) Then $vDBvalues &= $avArray[$x] & "," Else $vDBvalues &= _SQLite_FastEscape($avArray[$x]) & "," EndIf Case Else ; multi fields (2D Array) If IsNumber($avArray[$x][$y]) Then $vDBvalues &= $avArray[$x][$y] & "," Else $vDBvalues &= _SQLite_FastEscape($avArray[$x][$y]) & "," EndIf EndSwitch Next $vDBvalues = StringTrimRight($vDBvalues, 1) ; remove last comma EndFunc ;==>___BuildRecord Func ___InsertChain(ByRef $sDBfields, ByRef $vDBvaluesChain) If Not _SQLite_Exec(-1, "INSERT INTO array (" & $sDBfields & ") VALUES (" & $vDBvaluesChain & ");") = $SQLITE_OK Then $g__sSQLiteError = _SQLite_ErrMsg() _SQLite_Exec($g__hMemDb, "DROP TABLE array") ; delete the temporary table Return SetError(3, 0, "") EndIf EndFunc ;==>___InsertChain previous version is in the spoiler A simple example of use: #include <ArraySQL.au3> Local $x, $y, $sQuery, $aResult ; ------------------------------------------------------------ ; populate an array with random data to be managed for example Local $Array[1000][5] For $x = 0 To 999 For $y = 0 To 4 $Array[$x][$y] = Random(0, 100, 1) Next Next ; ------------------------------------------------------------ ; returns only rows where first column (column0) contains a value < 10 $sQuery = "SELECT * FROM array WHERE column0 < 10;" $aResult = _ArraySQL($Array, $sQuery) If Not @error Then _ArrayDisplay($aResult, "only data < 10 in column 0") Else MsgBox(0, "error", $g__sSQLiteError) EndIf ; ; returns all rows ordered by first column (column0) and then fourth by column (column3) $sQuery = "SELECT * FROM array ORDER BY column0,column3;" $aResult = _ArraySQL($Array, $sQuery) If Not @error Then _ArrayDisplay($aResult, "Ordered by column 0 and 3") Else MsgBox(0, "error", $g__sSQLiteError) EndIf P.S. improvements, corrections and suggestions are welcome1 point
-
I feel like I'm in a confessional... Please forgive me, I think it's been 8 years since I've asked a question in the GH&S. I've been putting together a helpful array of udf's for MSHTML events. I've come across two event interface names that are not cooperating. Of all the reading I've done, it looks like most of them directly interact with the element through the IID but I'll be damned if I can figure it out correctly. Here are the links: http://msdn.microsoft.com/en-us/library/aa769636(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/aa743143(v=vs.85).aspx Anyone have a bone to throw (Debug code below)? #include <IE.au3> #include <Debug.au3> _DebugSetup() _DebugCOMError() _Example() ConsoleWrite(@error & ":" & @extended & @CRLF) Func _Example() Local $oIE = _IECreate() If Not IsObj($oIE) Then Return SetError(1, 0, 0) EndIf _IEDocWriteHTML($oIE, Example_GetHTML()) Local $oDoc = $oIE.document Local $oPW = $oDoc.parentWindow Local $oForm = _IEFormGetCollection($oIE, 0) Local $oFName = _IEGetObjByName($oIE, "firstname") Local $oLName = _IEGetObjByName($oIE, "lastname") Local $oEmail = _IEGetObjByName($oIE, "email") Local $oMSex = _IEGetObjByName($oIE, "msex") Local $oFSex = _IEGetObjByName($oIE, "fsex") Local $oSubmit = _IEGetObjById($oIE, "submit2") Local $oReset = _IEGetObjById($oIE, "reset") Local $aOTmp[] = [$oIE, $oDoc, $oPW, $oForm, $oFName, $oLName, _ $oEmail, $oMSex, $oFSex, $oSubmit, $oReset] Local $oEvent For $i = 0 To UBound($aOTmp) - 1 $oEvent = ObjEvent($aOTmp[$i], "__Example_", "HTMLElementEvents2") If Not @error Then ConsoleWrite("Found Element Object: " & $i & @CRLF) ExitLoop EndIf $oEvent = ObjEvent($aOTmp[$i], "__Example_", "HTMLControlElementEvents2") If Not @error Then ConsoleWrite("Found Control Element Object: " & $i & @CRLF) ExitLoop EndIf Next While WinExists(HWnd($oIE.hwnd)) Sleep(10) WEnd _IEQuit($oIE) EndFunc Func __Example_onClick(ByRef $oObj) Example_Handler($oObj) EndFunc Func Example_Handler(ByRef $oObj) ConsoleWrite($oObj.type & @CRLF) EndFunc Func Example_GetHTML() Local $sHTML = "" $sHTML &= "0x3C21444F43545950452068746D6C3E0D0A3C68746D6C3E0D0A3C626F64" $sHTML &= "793E0D0A0D0A203C464F524D206E616D653D22736F6D65666F726D223E0D" $sHTML &= "0A202020203C503E0D0A202020204669727374206E616D653A203C494E50" $sHTML &= "555420747970653D227465787422206E616D653D2266697273746E616D65" $sHTML &= "223E3C42523E0D0A202020204C617374206E616D653A203C494E50555420" $sHTML &= "747970653D227465787422206E616D653D226C6173746E616D65223E3C42" $sHTML &= "523E0D0A20202020656D61696C3A203C494E50555420747970653D227465" $sHTML &= "787422206E616D653D22656D61696C223E3C42523E0D0A202020203C494E" $sHTML &= "50555420747970653D22726164696F22206E616D653D226D736578222076" $sHTML &= "616C75653D224D616C65223E204D616C653C42523E0D0A202020203C494E" $sHTML &= "50555420747970653D22726164696F22206E616D653D2266736578222076" $sHTML &= "616C75653D2246656D616C65223E2046656D616C653C42523E0D0A202020" $sHTML &= "203C494E5055542069643D227375626D6974322220747970653D22737562" $sHTML &= "6D6974222076616C75653D2253656E64223E203C494E5055542069643D22" $sHTML &= "72657365742220747970653D227265736574223E0D0A202020203C2F503E" $sHTML &= "0D0A203C2F464F524D3E0D0A0D0A3C2F626F64793E0D0A3C2F68746D6C3E" Return BinaryToString($sHTML) EndFunc I'm not familiar with the ObjCreateInterface as of yet, but I have a feeling, before this is over, I will be (that seems to be the direction the code is heading me in from what I've read).1 point
-
New SciTE4AutoIt3 available with updated SciTE v3.4.4
jaberwacky reacted to Jos for a topic
The parameter has a typo in the history file and should be: highlight.current.word.stoponspace The SciTEGlobal.properties contains the correct naming.... sorry about that. Jos1 point -
Get exe file from file extention
JLogan3o13 reacted to water for a topic
I didn't say the question wasn't legit. Just wanted to know what the OP tries to achieve. When we know the goal it is much easier to suggest a solution.1 point -
Saving PDF with Autoit using different "PDF applications"
SorryButImaNewbie reacted to mLipok for a topic
look here1 point -
Provide the output of your labels, and buttons, and that can be done. (from the get all controls on window)...add a True to the second param.1 point
-
Great job jdelaney ! I made a similar script (without any filter), posted in the french forum : http://www.autoitscript.fr/forum/viewtopic.php?p=74100#p74100 Have a look to it : I used the RegExp method to avoid the use of Array.au31 point
-
Base64 Converter
mLipok reacted to mikeytown2 for a topic
I was working on the _INetSmtpMail so that it can use a smtp server that requires a login. I got that working here http://www.autoitscript.com/forum/index.ph...52entry146052 but AutoIt didn't have a base64 converter... i found a VBscript of a base64 converter here http://minasi.com/64.htm I grabbed the script and put it through the VBScript to AutoIt Converter http://www.autoitscript.com/forum/index.php?showtopic=12143 After some time i got the thing working, here it is... -Mikeytown2 -EDIT- Grab _Base64.au3 from the next post... its better1 point -
Quick PDF Library
mLipok reacted to realshyfox for a topic
Hy, I have a litle prob. with my code. I try to transform a normal PDF into 2UP booklet format but ... somewhere I seem to miss something. Please help me. The original code: N-Up pages, 2-Up Booklet -Rowan- private void btnBooklet_Click(object sender, EventArgs e) { QuickPDFAX0716.PDFLibrary QP = new QuickPDFAX0716.PDFLibrary(); int result = QP.UnlockKey("...Insert_License_Key_Here..."); if (result == 1) { // First, load the original document that you wish to use for this imposition test: QP.LoadFromFile(@"C:\Program Files\Quick PDF Library\Quick PDF Library 7.16 Reference Guide.pdf"); // Then we get the number of pages in the original document: int originalPageCount = QP.PageCount(); // Store the width and height of the pages from the original document: double w = QP.PageWidth(); double h = QP.PageHeight(); // Use the CapturePage function to capture every page in the original document. // Each captured page will be given a unique ID which can be used with the // DrawCapturedPage function. Temporarily store these ID's in an array: int[] capture = new int[originalPageCount]; int indexArray = 0; for (int pageTest = 1; pageTest <= originalPageCount; pageTest++) { capture[indexArray] = QP.CapturePage(1); indexArray++; if (QP.PageCount() == 1) { // After a page has been captured it's removed from the document in memory, // but we can't have a document with no pages, so a temporary page must be // created until the imposed pages have been added to the document. QP.NewPage(); } } int requiredPages = 0; // Now calculate the required number of pages for the 2-up booklet: if (originalPageCount == 1) { requiredPages = 1; } else { requiredPages = originalPageCount / 2; } // Add the required number of pages to the end of the document, using the NewPages function: QP.NewPages(requiredPages); int captureIndex = 0; // Now loop through each new page in the document and draw the captured pages. Two captured // pages will be drawn on each new page. The first captured page is drawn on the left, the // second on the right, and then it moves on to the next new page and repeats the process: for (int page = 1; page <= requiredPages + 1; page++) { QP.SelectPage(page); QP.SetPageDimensions(w * 2, h); for (int i = 0; i <= 0; i++) { if (i <= 1) { // Draw left if (captureIndex != capture.Length) { QP.DrawCapturedPage(capture[captureIndex], 0, h, w, h); QP.DrawText(100, 25, "Page: " + captureIndex); captureIndex++; } // Draw right if (captureIndex != capture.Length) { QP.DrawCapturedPage(capture[captureIndex], 560, h, w, h); QP.DrawText(w, 25, "Page: " + captureIndex); captureIndex++; } } } } // Delete the extra page that was created when the original pages were captured QP.DeletePages(QP.PageCount(), 1); // Save the new 2-up booklet QP.SaveToFile(@"C:\temp\Manual_Booklet.pdf"); } else { MessageBox.Show("Sorry, but the license key you provided could not be validated."); } }AutoIt Code: $QP = ObjCreate("QuickPDFAX0725.PDFLibrary") Global $MyPDF, $MyPDFnUP $MyPDF = "something.pdf" $MyPDFnUP = "something_nup.pdf" _PDFnUP($MyPDF, $MyPDFnUP) Func _PDFnUP($MyPDF, $MyPDFnUP) If $QP.UnlockKey("...Insert_License_Key_Here...") = 1 Then $QP.LoadFromFile($MyPDF) $PgCount = $QP.PageCount() Dim $CaptureArray[$PgCount] $w = $QP.PageWidth() $h = $QP.PageHeight() For $n = 0 To $PgCount - 1 Step 1 $CaptureArray[$n] = $QP.CapturePage(1) If $QP.PageCount() = 1 Then $QP.NewPage() Next $RequiredPages = 0 If $PgCount = 1 Then $RequiredPages = 1 Else $RequiredPages = $PgCount/2 EndIf $QP.NewPages($RequiredPages) $CaptureIndex = 0 For $m = 1 To $RequiredPages Step 1 $QP.SelectPage($m) $QP.SetPageDimensions($w * 2, $h) For $i = 0 To 0 Step 1 If $i <= 1 Then If $CaptureIndex <> UBound($CaptureArray) Then $QP.DrawCapturedPage($CaptureArray[$CaptureIndex], 0, $h, $w, $h) ; $QP.DrawCapturedPage($CaptureArray[$CaptureIndex], [s]2500[/s], $h, $w, $h) ;$QP.DrawCapturedPage($CaptureArray[$CaptureIndex], 500, $h, $w, $h) $CaptureIndex = $CaptureIndex + 1 EndIf If $CaptureIndex <> UBound($CaptureArray) Then ; $QP.DrawCapturedPage($CaptureArray[$CaptureIndex], 0, $h, $w, $h) ;$QP.DrawCapturedPage($CaptureArray[$CaptureIndex], [s]2500[/s], $h, $w, $h) $QP.DrawCapturedPage($CaptureArray[$CaptureIndex], 500, $h, $w, $h) $CaptureIndex = $CaptureIndex + 1 EndIf EndIf Next Next $QP.DeletePages($QP.PageCount(), 1) $QP.SaveToFile($MyPDFnUP) $QP.LoadFromFile($MyPDFnUP) $PgCount = $QP.PageCount() $QP.ExtractPages(1, $PgCount - 1) $QP.SaveToFile("New_" &$MyPDFnUP) EndIf EndFunc ;==> _PDFnUPThe error is that it doesn´t write two pages up but one page up.Thanks. Sorry. I should´ve looked better. Tired1 point