Jump to content
Cristin

Copy Range of cells from Excel between two values

Recommended Posts

Dear all,

first of all hi.

I`m in trouble, again 😕

I can`t find right solution, tried all possible combinations generated by my mind and nothing.

I need to copy range of values depending by values from two different cells in excel sheet.

I put an example in attachment.

image.png.a50b062f5de2466c2fdcbdf3e44ed462.png

I have two values which is never changed (is changed only TEXT). I need to copy all the rows from VALUE 1 to VALUE 2 in new Sheets (Output 1, Output 2, ... , Output X).

It is possible to do this using Autoit?Â đŸ€”

Also in attachment you can find last example which I have tried and it`s something near, it is copying by _Excel_RangeFind row with needed VALUE 1 but I need to copy whole range from VALUE 1 to VALUE 2Â đŸ˜” ( see in attachment examples).

Thank you very much, in advance, for your support, solution really will make my life much easier 🙃

Have a nice day all of you!

Best Regards,

Cristin

Book1.xlsx something.au3

Share this post


Link to post
Share on other sites

Quick and dirty solution to solve the copy/paste problem (and a starter for the rest of the script).
Excel starts searching at the row following the current row. So when you start at the top of a worksheet and the first hit is in row 1 you will get this hit at the end of the returned array. I fix this by moving the last row of the array to the top of the array (but a check needs to be added if "value 1" can't always be found in row 1).
After I have found the start rows ("value 1") I search for the end rows ("value 2"). Then I copy all ranges to the same worksheet  with an offset to column "M".

#include <Array.au3>
#include <Excel.au3>

Local $aDiskInfo[0][80], $aWorkbook
Local $sWorkbook = @ScriptDir & "\Book1.xlsx"
Local $sSheetInput = "Sheet1"
Local $bSheetDelete = False ;~ Change to True to create new sheet.
Local $sSheetOutput = "Output"

Local $oExcel = _Excel_Open()
If @error Then Exit
Local $oWorkbook = _Excel_BookOpen($oExcel, $sWorkbook)
If @error Then Exit _Excel_Close($oExcel)

; Find all occurrences of value "input" (partial match)
Local $aResult1 = _Excel_RangeFind($oWorkbook, "VALUE 1", $oWorkbook.Sheets($sSheetInput).Usedrange)
If @error Then Exit
_ArrayInsert($aResult1, 0) ; Insert an empty row
_ArraySwap($aResult1, 0, Ubound($aResult1, 1) - 1) ; Move the last row to row 0
_ArrayDelete($aResult1, Ubound($aResult1, 1) - 1) ; Delete the last row
Local $aResult2 = _Excel_RangeFind($oWorkbook, "VALUE 2", $oWorkbook.Sheets($sSheetInput).Usedrange)

For $i = 0 To UBound($aResult1) - 1
    $iRowStart = $oWorkbook.Sheets($sSheetInput).Range($aResult1[$i][2]).Row
    $iRowEnd = $oWorkbook.Sheets($sSheetInput).Range($aResult2[$i][2]).Row
    _Excel_RangeCopyPaste($oWorkbook.Sheets($sSheetInput), "A" & $iRowStart & ":K" & $iRowEnd, "M" & $iRowStart)
Next

 


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2020-10-10 - Version 1.5.2.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2020-12-15 - Version 1.6.3.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2020-06-27 - Version 1.3.2.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

 

Share this post


Link to post
Share on other sites
12 hours ago, water said:

Quick and dirty solution to solve the copy/paste problem (and a starter for the rest of the script).

Dear @water, GREAT solution, it works perfect, I`m very happyÂ đŸ€©

Now I should found a solution to create new sheets for each copied range. It shouldn`t be a hard work for me.

Thank you a lot, again I see that this forum is an excellent place!

Share this post


Link to post
Share on other sites

:)
If you encounter problems don't hesitate to post here again ;)


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2020-10-10 - Version 1.5.2.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2020-12-15 - Version 1.6.3.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2020-06-27 - Version 1.3.2.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

 

Share this post


Link to post
Share on other sites
3 hours ago, water said:

:)
If you encounter problems don't hesitate to post here again ;)

Sorry but, I`m stuck again 😳

Can`t make it to work right 😖

 

Func _ExcelSheetAddAfter($oXl, $sAfterSheet = "", $sNewSheetName = "")
    If Not IsObj($oXl) Then Return SetError(1, 0, 0)
    Local $iSheetCount = $oXl.ActiveWorkbook.Sheets.Count
    If $sAfterSheet = "" Then
        $oXl.ActiveWorkBook.WorkSheets.Add(Default, $oXl.ActiveWorkbook.Sheets($iSheetCount)).Activate
    Else
        For $i = 1 To $iSheetCount
            If $oXl.ActiveWorkbook.Sheets($i).Name = $sAfterSheet Then
                $oXl.ActiveWorkBook.WorkSheets.Add(Default, $oXl.ActiveWorkbook.Sheets($i)).Activate
                ExitLoop
            EndIf
        Next
        If $i > $iSheetCount Then Return SetError(2, 0, 0)
    EndIf
    If $sNewSheetName <> "" Then $oXl.ActiveSheet.Name = $sNewSheetName
    Return 1
EndFunc

đŸ€”

Share this post


Link to post
Share on other sites

Hey,

Haven't used Excel UDF really but, how about if you change

$oXl.ActiveWorkBook.WorkSheets.Add(Default, $oXl.ActiveWorkbook.Sheets($iSheetCount)).Activate

into 

$oXl.ActiveWorkBook.WorkSheets.Add(Default, $oXl.ActiveWorkbook.Sheets($iSheetCount))

I think any new sheets added should be activated without any intervention.

Share this post


Link to post
Share on other sites

You should use function _Excel_SheetAdd. All functions starting with _Excel* without a second underscore belong to a very, very old version of AutoIt (< 3.3.12.0).
You can't mix the old and new versions. Details about this script breaking change can be found here.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2020-10-10 - Version 1.5.2.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2020-12-15 - Version 1.6.3.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2020-06-27 - Version 1.3.2.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

 

Share this post


Link to post
Share on other sites
3 hours ago, water said:

You should use function _Excel_SheetAdd. All functions starting with _Excel* without a second underscore belong to a very, very old version of AutoIt (< 3.3.12.0).
You can't mix the old and new versions. Details about this script breaking change can be found here.

Yeah, I found a solution ... but, I can copy only text without formatting. Hope you can help me with this last one trouble.

 

#include <Array.au3>
#include <Excel.au3>

Local $aDiskInfo[0][80], $aWorkbook
Local $sWorkbook = @ScriptDir & "\book1.xlsx"
Local $sSheetInput = "Sheet1"
Local $bSheetDelete = True ;~ Change to True to create new sheet.
Local $sSheetOutput = "Output"
Local $s=0

Local $oExcel = _Excel_Open()
If @error Then Exit
Local $oWorkbook = _Excel_BookOpen($oExcel, $sWorkbook)
If @error Then Exit _Excel_Close($oExcel)

; Find all occurrences of value "input" (partial match)
Local $aResult1 = _Excel_RangeFind($oWorkbook, "VALUE 1", $oWorkbook.Sheets($sSheetInput).Usedrange)
If @error Then Exit
_ArrayInsert($aResult1, 0) ; Insert an empty row
_ArraySwap($aResult1, 0, Ubound($aResult1, 1) - 1) ; Move the last row to row 0
_ArrayDelete($aResult1, Ubound($aResult1, 1) - 1) ; Delete the last row
Local $aResult2 = _Excel_RangeFind($oWorkbook, "VALUE 2", $oWorkbook.Sheets($sSheetInput).Usedrange)

For $i = 0 To UBound($aResult1) - 1
    $iRowStart = $oWorkbook.Sheets($sSheetInput).Range($aResult1[$i][2]).Row
    $iRowEnd = $oWorkbook.Sheets($sSheetInput).Range($aResult2[$i][2]).Row
    $s=$i+1
    _Excel_SheetAdd($oWorkbook,$s)
    $read=_Excel_RangeRead($oWorkbook,$sSheetInput,"A" & $iRowStart & ":K" & $iRowEnd)
    _Excel_RangeWrite($oWorkbook,$s,$read,"A1")
Next

Thank you in advance for your support!

Share this post


Link to post
Share on other sites

_Excel_RangeRead just reads the "value, formula or displayed text" of a range. Means: Just the content of cells.
You need to use _Excel_RangeCopyPaste.
 


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2020-10-10 - Version 1.5.2.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2020-12-15 - Version 1.6.3.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2020-06-27 - Version 1.3.2.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

 

Share this post


Link to post
Share on other sites
23 hours ago, water said:

_Excel_RangeRead just reads the "value, formula or displayed text" of a range. Means: Just the content of cells.
You need to use _Excel_RangeCopyPaste.
 

DONEÂ đŸ€©

#include <Array.au3>
#include <Excel.au3>

Local $aDiskInfo[0][80], $aWorkbook
Local $sWorkbook = FileOpenDialog("Choose Excel file", @ScriptDir, "Excel (*.xls;*.xlsx)")
Local $sSheetInput = "Sheet"
Local $bSheetDelete = True ;~ Change to True to create new sheet.
Local $sSheetOutput = "Output"
Local $s=0

Local $oExcel = _Excel_Open()
If @error Then Exit
Local $oWorkbook = _Excel_BookOpen($oExcel, $sWorkbook)
If @error Then Exit _Excel_Close($oExcel)

; Find all occurrences of value "input" (partial match)
Local $aResult1 = _Excel_RangeFind($oWorkbook, "VALUE 1", $oWorkbook.Sheets($sSheetInput).Usedrange)
If @error Then Exit
_ArrayInsert($aResult1, 0) ; Insert an empty row
_ArraySwap($aResult1, 0, Ubound($aResult1, 1) - 1) ; Move the last row to row 0
_ArrayDelete($aResult1, Ubound($aResult1, 1) - 1) ; Delete the last row
Local $aResult2 = _Excel_RangeFind($oWorkbook, "VALUE 2", $oWorkbook.Sheets($sSheetInput).Usedrange)

For $i = 0 To UBound($aResult1) - 1
    $iRowStart = $oWorkbook.Sheets($sSheetInput).Range($aResult1[$i][2]).Row
    $iRowEnd = $oWorkbook.Sheets($sSheetInput).Range($aResult2[$i][2]).Row
    $s=$i+1
    $read=_Excel_SheetAdd($oWorkbook,$s)
    _Excel_RangeCopyPaste($oWorkbook.Sheets($sSheetInput),"A" & $iRowStart & ":K" & $iRowEnd, $oWorkbook.Sheets($s).Range("A1"))
Next

If you have some ideas how to improve this code, please, I`ll be glad.

Thank you for support â˜ș

Have a great day!

BR

Share this post


Link to post
Share on other sites

I suggest to use variable names you can easily understand what they are used for:

For $i = 0 To UBound($aResult1) - 1
    $iRowStart = $oWorkbook.Sheets($sSheetInput).Range($aResult1[$i][2]).Row
    $iRowEnd = $oWorkbook.Sheets($sSheetInput).Range($aResult2[$i][2]).Row
    $iSheetIndex = $i + 1
    $read = _Excel_SheetAdd($oWorkbook, $iSheetIndex)
    _Excel_RangeCopyPaste($oWorkbook.Sheets($sSheetInput),"A" & $iRowStart & ":K" & $iRowEnd, $oWorkbook.Sheets($iSheetIndex).Range("A1"))
Next

If you need to enhance speed you could create all worksheets with a single call to _Excel-SheetAdd before the loop and specify the number of sheets to create.

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2020-10-10 - Version 1.5.2.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2020-12-15 - Version 1.6.3.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2020-06-27 - Version 1.3.2.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

 

Share this post


Link to post
Share on other sites

Dear @water

when i use this 

_Excel_BookOpen 

@erorr = 3 come out 

this error begin after i changed to excel 13

any ideas please


 
#include <Array.au3>
#include <Excel.au3>

Local $aDiskInfo[0][80], $aWorkbook
Local $sWorkbook = FileOpenDialog("Choose Excel file", @ScriptDir, "Excel (*.xls;*.xlsx)")
Local $sSheetInput = "Sheet"
Local $bSheetDelete = True ;~ Change to True to create new sheet.
Local $sSheetOutput = "Output"
Local $s=0

Local $oExcel = _Excel_Open()
If @error Then Exit
Local $oWorkbook = _Excel_BookOpen($oExcel, $sWorkbook)
If @error Then Exit _Excel_Close($oExcel)

; Find all occurrences of value "input" (partial match)
Local $aResult1 = _Excel_RangeFind($oWorkbook, "VALUE 1", $oWorkbook.Sheets($sSheetInput).Usedrange)
If @error Then Exit
_ArrayInsert($aResult1, 0) ; Insert an empty row
_ArraySwap($aResult1, 0, Ubound($aResult1, 1) - 1) ; Move the last row to row 0
_ArrayDelete($aResult1, Ubound($aResult1, 1) - 1) ; Delete the last row
Local $aResult2 = _Excel_RangeFind($oWorkbook, "VALUE 2", $oWorkbook.Sheets($sSheetInput).Usedrange)

For $i = 0 To UBound($aResult1) - 1
    $iRowStart = $oWorkbook.Sheets($sSheetInput).Range($aResult1[$i][2]).Row
    $iRowEnd = $oWorkbook.Sheets($sSheetInput).Range($aResult2[$i][2]).Row
    $s=$i+1
    $read=_Excel_SheetAdd($oWorkbook,$s)
    _Excel_RangeCopyPaste($oWorkbook.Sheets($sSheetInput),"A" & $iRowStart & ":K" & $iRowEnd, $oWorkbook.Sheets($s).Range("A1"))
Next

 

Share this post


Link to post
Share on other sites

Can you please check the content of $sWorkbook before _Excel_BookOpen to make sure it contains a valid path?
 


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2020-10-10 - Version 1.5.2.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2020-12-15 - Version 1.6.3.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2020-06-27 - Version 1.3.2.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

 

Share this post


Link to post
Share on other sites

In addition I suggest to use

#include <FileConstants.au3>
Local $sWorkbook = FileOpenDialog("Choose Excel file", @ScriptDir, "Excel (*.xls;*.xlsx)", BitOR($FD_FILEMUSTEXIST, $FD_PATHMUSTEXIST))
If @error Then Exit ; User cancelled the file selection dialog or there is a problem with the file filter

 


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2020-10-10 - Version 1.5.2.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2020-12-15 - Version 1.6.3.1) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2020-06-27 - Version 1.3.2.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By robertocm
      An example of updating an excel file with a join between excel range and access tables.
      #include <Excel.au3> #include <Array.au3> #include <MsgBoxConstants.au3> ;#include <WinAPIFiles.au3> ;Permitir unha Ășnica instancia da aplicaciĂłn #include <Misc.au3> ;_Singleton("ADO_Update_Excel_From_Access", 0) If _Singleton("ADO_Update_Excel_From_Access", 1) = 0 Then MsgBox($MB_SYSTEMMODAL, "Warning", "An occurrence of test is already running") Exit EndIf Opt("MustDeclareVars", 1) Opt("TrayIconDebug", 1) OnAutoItExitRegister("OnAutoItExit") #===== CONFIG ===== Global $sFilePath = @ScriptDir & "\test.xlsx" Global $sFilePath2 = @ScriptDir & "\test.mdb" Global $testmdb = "[;Database=" & $sFilePath2 & ";PWD=123]" ;~ Global $excel = "[Excel 12.0 Xml;HDR=NO;IMEX=1;DATABASE=" & $sFilePath& "]" ;Global $testsqlserver = "[odbc;Driver={SQL Server};SERVER=10.0.0.99;DATABASE=MyDatabaseName;UID=MyUser;PWD=MyPassword]" #===== ADODB ===== Global $cn, $rst, $sSQL, $SubSQL ;Help: COM Error Handling ;_ErrADODB From spudw2k ;https://www.autoitscript.com/forum/topic/105875-adodb-example/ Global $errADODB = ObjEvent("AutoIt.Error","_ErrADODB") Global Const $iCursorType = 3 ;0 adOpenForwardOnly, 3 adOpenStatic Global Const $iLockType = 3 ;1 adLockReadOnly, 3 adLockOptimistic Global Const $iOptions = 1 ; Options, 1 Evaluates as a textual definition of a command or stored procedure call ; 2 adCmdTable $cn = ObjCreate("ADODB.Connection") ; Create a connection object $rst = ObjCreate("ADODB.Recordset") ; Create a recordset object ;Global $sADOConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & $sFilePath2 & ";Jet OLEDB:Database Password=123" ;Global $sADOConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & $sFilePath2 & ";Jet OLEDB:Database Password=123" ;Global $sADOConnectionString = 'Driver={Microsoft Access Driver (*.mdb)};Dbq=' & $sFilePath2 & ';uid=;pwd=MyPassword;' ;~ ;Global $sADOConnectionString = 'Provider=SQLOLEDB;Data Source=10.0.0.99;Initial Catalog=MyDatabaseName;User Id=MyUser;Password=MyPassword;' ;~ ;Or if you’re using native client: ;~ ;stConnect = "Provider=SQLNCLI10;Data Source=... ;http://www.connectionstrings.com/ ;Xlsx files: Excel 2007 (and later) files with the Xlsx file extension ;[Also valid for] Using the Office 2007 OLEDB driver (ACE 12.0) to connect to older 97-2003 Excel workbooks ;cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & RutaXls & ";Extended Properties=Excel 12.0 Xml;" Global $sADOConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & $sFilePath & ";Extended Properties=""Excel 12.0 Xml;HDR=NO"";" ;Global $sADOConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & $sFilePath & ";Extended Properties=""Excel 12.0;HDR=NO;IMEX=1"";" ;Global $sADOConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & $sFilePath & ";Extended Properties=Excel 8.0;" ;Global $sADOConnectionString = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=" & $sFilePath & ";ReadOnly=0;" ;https://www.w3schools.com/asp/prop_rs_cursorlocation.asp ;A Recordset object inherits this setting from the associated Connection object. ;This property is read-only on an open Recordset object, and read/write on a Connection object or on a closed Recordset object. $cn.CursorLocation = 2 ;2 adUseServer, 3 adUseClient $cn.CommandTimeout = 30 ;https://stackoverflow.com/questions/31941487/open-adodb-connection-to-excel-file-in-read-only-mode ;try Mode = adModeRead instead ;By the way, do not put adModeRead in the connections string, but just before openning your connection, add this line: rsConn.Mode = adModeRead ;I tried your suggestion, however since in VBA we do not have direct access to the ADODB built-in constants, I set rsCon.Mode = 1 ;as defined in the file adovbs.inc located in the folder "C:\Program Files\Common Files\System\ado" ;and although I watched the rsCon.Mode value being set to adModeRead while debugging, I still have the same problem and the application tries to access the file in Write/Edit mode. ;https://www.w3schools.com/asp/prop_rec_mode.asp ;$cn.Mode = 1 ;Read-only $cn.Open($sADOConnectionString) ; Open the connection ;MsgBox(0, "", $cn.ConnectionString) $sSQL = "UPDATE (([Sheet1$A2:C11] a" _ & " INNER JOIN " & $testmdb & ".[Order_Details] b ON a.F1 = b.ID)" _ & " INNER JOIN " & $testmdb & ".[Orders] c ON b.ID = c.ID)" _ & " INNER JOIN " & $testmdb & ".[Customers] d ON c.CustomerID = d.ID" _ & " SET a.F2 = c.OrderDate, a.F3 = d.CompanyName;" $cn.Execute($sSQL, Default, 1 + 0x80) ;adCmdText = 1 , adExecuteNoRecords = 0x80 $sSQL = "SELECT F2, F3, Sum(Quantity * UnitPrice) As Amount" _ & " FROM [Sheet1$A2:C11] AS a INNER JOIN " & $testmdb & ".[Order_Details] b ON a.F1 = b.ID" _ & " GROUP BY F2, F3" _ & " ORDER BY F2;" $rst.Open($sSQL, $cn, $iCursorType, $iLockType, $iOptions) ; Issue the SQL query If Not $rst.EOF = True Then Local $rstArray = $rst.GetRows() _ArrayDisplay($rstArray, "Test", "", $ARRAYDISPLAY_NOROW, "", "F1|F2|F3") $rst.Close $rst = 0 ;Release the recordset object ;$cmd = 0 $cn.Close ;Close the connection $cn = 0 ;Release the connection object Global $RecCount = UBound($rstArray) #===== EXCEL ===== Global $oMyError = ObjEvent("AutoIt.Error", "ErrFunc") ;Install a custom error handler Global $iEventError ; to be checked to know if com error occurs. Must be reset after handling. ;_DebugSetup() ;_DebugCOMError() ;water: force the Excel UDF to always start up a new instance by using: _Excel_Open(False, Default, Default, Default, True) ;Global $oAppl = _Excel_Open(True, False, False, Default, True) Global $oAppl = _Excel_Open() ;_Excel_Open(Default, Default, False, Default, Default) ;If @error Then Exit MsgBox(0, "Error", "Error _Excel_Open" & @CRLF & "@error = " & @error & ", @extended = " & @extended) ;https://www.autoitscript.com/forum/topic/185789-solved-excel_bookopen-without-wait/?do=findComment&comment=1334509 ;Restaurar en cada arquivo (algĂșn Application.Run pudo cambiar) ;$oAppl.EnableEvents = False $oAppl.DisplayAlerts = False ;~ ;Arquivo non bloqueado ;~ Global $iFileExists ;~ For $j = 0 To 60 ;~ $iFileExists = FileExists($sFilePath2) ;~ If $iFileExists Then ;~ While _WinAPI_FileInUse($sFilePath2) ;~ Sleep(1000) ;~ WEnd ;~ ExitLoop ;~ Else ;~ Sleep(1000) ;~ EndIf ;~ Next ;Create a new workbook with only 1 worksheet Global $oWorkbook = _Excel_BookNew($oAppl, 1) ;If @error Then Exit MsgBox(0, "Excel UDF: _Excel_BookNew Example 1", "Error creating new workbook." & @CRLF & "@error = " & @error & ", @extended = " & @extended) ;MsgBox(0, "Excel UDF: _Excel_BookNew Example 1", "Workbook has been created successfully with only 1 worksheets.") ;~ Global $oWorkbook = _Excel_BookOpen($oAppl, $sFilePath5, False, True) ;~ ;If @error Then Exit MsgBox(0, "Error", "Error _Excel_BookOpen: " & $sFilePath & @CRLF & "@error = " & @error & ", @extended = " & @extended) ;~ ;Create a new workbook with only 1 worksheet ;~ ;Global $oWorkbook = _Excel_BookNew($oAppl, 1) ;~ ;If @error Then Exit MsgBox(0, "Excel UDF: _Excel_BookNew Example 1", "Error creating new workbook." & @CRLF & "@error = " & @error & ", @extended = " & @extended) ;~ ;MsgBox(0, "Excel UDF: _Excel_BookNew Example 1", "Workbook has been created successfully with only 1 worksheets.") ;Sleep(3000) ;~ Global $sMessage, $sMessage2 ;~ SplashTextOn("TitleFoo", $sMessage, 580, 60, 900, 840, 1 + 4, "", 16) ;~ For $i = 1 To 10 ;~ $sMessage = $sMessage & "." ;~ $sMessage2 = @TAB & "Pausa " & $sMessage ;~ ControlSetText("TitleFoo", "", "Static1", $sMessage2) ;~ Sleep(1000) ;~ Next $oWorkbook.UpdateLinks = 2 ;xlUpdateLinksNever ;Global $oSheets = $oWorkbook.Sheets Global $oSheet = $oWorkbook.ActiveSheet ;Global $oSheet = $oWorkbook.Sheets("Sheet1") ;MsgBox(0, "", $oSheet.Name) $oSheet.Range("A1:C1").Font.Bold = True $oSheet.Range("A1:A" & $RecCount + 1).NumberFormat = "dd/mm" $oSheet.Range("B1:B" & $RecCount + 1).NumberFormat = "@" Global $oPageSetup = $oSheet.PageSetup With $oPageSetup .PrintTitleRows = "$1:$1" .PrintTitleColumns = "" .PrintArea = "" .LeftHeader = "&D" .CenterHeader = "Report" .RightHeader = "&P of &N" ;.LeftFooter = "&F {&A}" .CenterFooter = "" .RightFooter = "" .LeftMargin = 28 .RightMargin = 28 .TopMargin = 28 .BottomMargin = 28 .HeaderMargin = 15 .FooterMargin = 15 .PrintHeadings = False .PrintGridlines = True .PrintComments = -4142 .CenterHorizontally = False .CenterVertically = False .Orientation = 1 ;2 .Draft = False .FirstPageNumber = -4105 .Order = 1 .BlackAndWhite = True .Zoom = 100 EndWith ;https://www.autoitscript.com/forum/topic/195252-_excel_rangewrite-doesnt-write-array-from-adodb-getrows/ Global $TrstArray = $rstArray _ArrayTranspose($TrstArray) $oSheet.Range("A2:C" & $RecCount + 1).Value = $TrstArray Global $aArray2D[1][4] = [["Date", "Client", "Amount"]] _Excel_RangeWrite($oWorkbook, $oSheet, $aArray2D, $oSheet.Cells(1, 1)) ;Global $aArray1D[11] = ["ID", "Udes", "Descrip", "Matricula", "Kilos", "Proveedor", "Corredor", "Fecha", "Contrato", "Restan", "Tanque"] ;$oSheet.Range("A1:K1").value = $aArray1D ;Global $aArray2D[1][6] = [[$rstArray[$i][1], $rstArray[$i][2], $rstArray[$i][3], $rstArray[$i][4], $rstArray[$i][5], $rstArray[$i][6]]] ;_Excel_RangeWrite($oWorkbook, $oWorkbook.Activesheet, $aArray2D, $oSheet.Cells($UltimaFila, 1).Resize(1, 6)) ;If @error Then Exit MsgBox(0, "Error", "Error _Excel_RangeWrite: " & @CRLF & "@error = " & @error & ", @extended = " & @extended) ;Global $aArray2D[3][5] = [[11, 12, 13, 14, 15], [21, 22, 23, 24, 25], [31, 32, 33, 34, 35]] ;_Excel_RangeWrite($oWorkbook, Default, $aArray2D, "B1") ;Local $aArray1D[13] = ["Ped", "Archivo", "Abono", "NomCli", "H+I", "ACIDEZ", "CERAS", "E+U", "aa", "aa", "aa", "aa", "aa"] ;$oSheet.Range("A1:M1").value = $aArray1D ;$oSheet.Cells(1, 1).Resize(1, 13).value = $aArray1D ;_Excel_BookSaveAs($oWorkbook, $sFilePath, $xlOpenXMLWorkbook, True) ;$xlOpenXMLWorkbook 51 ;$xlExcel8 56 ;_Excel_BookClose($oWorkbook, False) ;_Excel_BookClose($oWorkbook, True) ;If @error Then Exit MsgBox(0, "Error", "Error _Excel_BookClose: " & $sFilePath & @CRLF & "@error = " & @error & ", @extended = " & @extended) ;~ While _WinAPI_FileInUse($sFilePath5) ;~ Sleep(1000) ;~ Wend ;~ Sleep(3000) ;$oAppl.EnableEvents = True $oAppl.DisplayAlerts = True ;https://www.autoitscript.com/forum/topic/136414-excel-close-problem/?do=findComment&comment=953433 ;$oAppl.Application.Quit ;$oAppl = "" ;https://www.autoitscript.com/forum/topic/166043-close-the-entire-application-of-excel/ ;https://www.autoitscript.com/forum/topic/166043-close-the-entire-application-of-excel/?do=findComment&comment=1262478 ;Run(@ComSpec & " /c " & 'taskkill /im excel.exe /f /t', "", @SW_HIDE) ;https://www.autoitscript.com/forum/topic/166043-close-the-entire-application-of-excel/?do=findComment&comment=1262830 ;water / Ok. Let's see if the problem is caused by open/close or by working with a workbook. Could you please try: ;#include <Excel.au3> ;$oExcel = _Excel_Open(False, False, False, False, True) ;$oExcelClose = _Excel_Close($oExcel, False, True) ;~ _Excel_Close($oAppl, False, Default) ;If @error Then Exit MsgBox(0, "Error", "Error _Excel_Close" & @CRLF & "@error = " & @error & ", @extended = " & @extended) ;~ Sleep(1000) ;~ ;Check excel closed ;~ Local $aProcesses = ProcessList("Excel.exe") ;~ ;_ArrayDisplay($aProcesses) ;~ If $aProcesses[0][0] > 0 Then ;~ ;https://www.autoitscript.com/forum/topic/166043-close-the-entire-application-of-excel/?do=findComment&comment=1263191 ;~ ;@water, thanks for your help so far, at least we pinned down that it's not a UDF bug. :) ;~ ;For now I will use a crude workaround by closing the most recent Excel.exe instance: ;~ ProcessClose($aProcesses[$aProcesses[0][0]][1]) ;~ Sleep(100) ;just to allow some time for the process to definitely close (if it does close) ;~ EndIf Else $rst.Close $rst = 0 ; Release the recordset object $cn.Close ; Close the connection $cn = 0 ; Release the connection object ;Disconnect MsgBox(262144, "", "Empty Recordset", 5) EndIf ;This is a custom error handler Func ErrFunc() Local $HexNumber = Hex($oMyError.number, 8) ;~ MsgBox(0, "", "We intercepted a COM Error !" & @CRLF & _ ;~ "Number is: " & $HexNumber & @CRLF & _ ;~ "WinDescription is: " & $oMyError.windescription) ConsoleWrite("-> We intercepted a COM Error !" & @CRLF & _ "-> err.number is: " & @TAB & $HexNumber & @CRLF & _ "-> err.source: " & @TAB & $oMyError.source & @CRLF & _ "-> err.windescription: " & @TAB & $oMyError.windescription & _ "-> err.scriptline is: " & @TAB & $oMyError.scriptline & @CRLF) $iEventError = 1 ; Use to check when a COM Error occurs EndFunc ;==>ErrFunc Func _ErrADODB() Msgbox(0,"ADODB COM Error","We intercepted a COM Error !" & @CRLF & @CRLF & _ "err.description is: " & @TAB & $errADODB.description & @CRLF & _ "err.windescription:" & @TAB & $errADODB.windescription & @CRLF & _ "err.number is: " & @TAB & hex($errADODB.number,8) & @CRLF & _ "err.lastdllerror is: " & @TAB & $errADODB.lastdllerror & @CRLF & _ "err.scriptline is: " & @TAB & $errADODB.scriptline & @CRLF & _ "err.source is: " & @TAB & $errADODB.source & @CRLF & _ "err.helpfile is: " & @TAB & $errADODB.helpfile & @CRLF & _ "err.helpcontext is: " & @TAB & $errADODB.helpcontext, 5) Local $err = $errADODB.number If $err = 0 Then $err = -1 ;Devolver datos error Local $sFilePath = @DesktopDir & "\error.txt" ;Open the file for write access. Local $hFileOpen = FileOpen($sFilePath, 2) ;If $hFileOpen = -1 Then ;MsgBox(0, "", "An error occurred when reading/writing the file.") ;EndIf FileWrite($hFileOpen, "ADODB COM Error" & Chr(1) & _ "err.description is: " & @TAB & $errADODB.description & Chr(1) & _ "err.windescription:" & @TAB & $errADODB.windescription & Chr(1) & _ "err.number is: " & @TAB & hex($errADODB.number,8) & Chr(1) & _ "err.lastdllerror is: " & @TAB & $errADODB.lastdllerror & Chr(1) & _ "err.scriptline is: " & @TAB & $errADODB.scriptline & Chr(1) & _ "err.source is: " & @TAB & $errADODB.source & Chr(1) & _ "err.helpfile is: " & @TAB & $errADODB.helpfile & Chr(1) & _ "err.helpcontext is: " & @TAB & $errADODB.helpcontext _ ) ;Close the handle returned by FileOpen. FileClose($hFileOpen) $rst = 0 ;$cmd = 0 $cn.Close $cn = 0 ;Disconnect Exit EndFunc Func OnAutoItExit() $rst = 0 ;Release the recordset object If IsObj($cn) Then If $cn.State > 0 Then $cn.Close ;adStateOpen Close the connection $cn = 0 ; Release the connection object EndIf EndFunc  
      example_files.zip
    • By sudeepjd
      I was looking for a UDF using which I could Add and Update Pivot tables and Pivot Charts in Excel easily and could not find one that I could use. So I build this UDF. 
      It has the following functions :
      _ExcelPivot_CreateCache ; Easily Create a pivot table data cache from a Sheet _ExcelPivot_CreateTable ; Create a table from a cache at a specified location on the sheet _ExcelPivot_RefreshTable ; Refresh the datatable data with a new cache _ExcelPivot_AddField ; Add a Field and Aggregate function to the Datatable _ExcelPivot_AddFilter ; Adds in the Filter to a specific field _ExcelPivot_ClearFilter ; Removes the filter for a field or all the filters in the table _ExcelPivot_GetRange ; Get specific areas of a Pivot as a Range Object _ExcelPivot_AddChart ; Add a Pivot Chart linked to a specific Pivot table Attached the UDF to this post.
      Please do let me know if I can improve or add additional functions to it.
      A detailed example on the usage is below. The excel file and the example can be downloaded from the Example.zip file attached.
      #include "ExcelPivot.au3" $oExcel = _Excel_Open() $oBook = _Excel_BookOpen($oExcel, @ScriptDir & "\TestPivot.xlsx") ;Create a Sheet to put the pivot into $pSheet = _Excel_SheetAdd($oBook, -1, False, 1) $pSheet.Name = "Pivot" ;Get the cache for the pivot table $pCache = _ExcelPivot_CreateCache($oBook, "Data") ;Add in the Pivot Table from the Cache _ExcelPivot_CreateTable($pCache, $pSheet, "A1", "FruitsPivot") ;Add in the Fields into the Pivot _ExcelPivot_AddField($pSheet, "FruitsPivot", "Category", "Filter") _ExcelPivot_AddField($pSheet, "FruitsPivot", "Product", "Row") _ExcelPivot_AddField($pSheet, "FruitsPivot", "Amount", "Value", "Sum", 1) ;Add in a Running total to the Pivot _ExcelPivot_AddField($pSheet, "FruitsPivot", "Amount", "Value", "Sum", 2, "PercentageRunningTotal", "Product") ;Filter only the fruits _ExcelPivot_Filter($pSheet, "FruitsPivot", "Category", "Fruit") ;Draw a Paretto Chart $chart = _ExcelPivot_AddChart($oBook, $pSheet, "FruitsPivot", "ColumnClustered", "Paretto", "E2", 570) $chart.Chart.FullSeriesCollection(1).ApplyDataLabels $chart.Chart.FullSeriesCollection(2).ChartType = 4 ;Change the percentage to a line graph $chart.Chart.FullSeriesCollection(2).AxisGroup = 2 ;Move it to secondary axis $chart.Chart.Axes(2, 2).MaximumScale = 1 ;Adjust to scale to 100% max  
       
      ExcelPivot.au3 Example.zip
    • By Page2PagePro
      Excel VBA's IDE registers a Control-y as "cut this line of code".
      For those prone to Undo/Redo (Ctrl+Z/Ctrl+Y) you may find frustration when your code in the editor does not redo, but in fact clears your active line of code while killing redo history.
      Though not perfect, I keep this tool running in background on startup.
      The purpose is to allow Cltr+Y to act normally throughout Windows and Office and only interact *differently* with the "Microsoft Visual Basic for Applications" window that is active.
      If the Standard Menu bar exists, it'll try to click the ReDo (Blue Arrow to the right), else "Alt+e, r" keystrokes (less desired).
       
      Here's the code:
      Opt('MustDeclareVars', 1) Opt("WinTitleMatchMode", 1) HotKeySet("^y", "TriggerRedo") While 1 Sleep(10) WEnd Func TriggerRedo() ConsoleWrite("TriggerRedo()" & @CRLF) Local $title = "Microsoft Visual Basic for Applications - " Local $hWnd If WinExists($title) And WinActive($title) Then ;~ Parent Window Handle $hWnd = WinGetHandle($title) Local $aWindowPos = WinGetPos($hWnd) ;~ Control Bar Handle, Position and If Visible Local $sControlID = "[CLASS:MsoCommandBar; TEXT:Standard;]" Local $hStandardBar = ControlGetHandle($hWnd, "", $sControlID) Local $bIsVisible = ControlCommand($hWnd, "", $sControlID, "IsVisible") If $hStandardBar And $bIsVisible Then ConsoleWrite("Using Mouse Click." & @CRLF) ;~ Determine Redo button location on visible Control Bar Local $aBarPos = ControlGetPos($hWnd, "", $sControlID) Local $mX = $aWindowPos[0] + $aBarPos[0] + 217 + Int(23/2) Local $mY = $aWindowPos[1] + $aBarPos[1] + 27 + Int(22/2) MouseClick("Left", $mX, $mY, 1, 0) Else ConsoleWrite("Using VBA Send Keys." & @CRLF) $sControlID = "[CLASS:MsoCommandBar; TEXT:Menu Bar;]" Local $hMenuBar = ControlGetHandle($hWnd, "", $sControlID) ControlSend($hWnd, "", $hMenuBar, "!e") ;~ Send("r") $sControlID = "[CLASS:MsoCommandBarPopup; TEXT:Edit;]" Local $hPopupBar = ControlGetHandle($hWnd, "", $sControlID) ControlSend($hWnd, "", $hPopupBar, "r") EndIf Else ConsoleWrite("Using NATIVE Send Keys." & @CRLF) HotKeySet("^y") Send("^y") ;~ may cause "yyy..." when held HotKeySet("^y", "TriggerRedo") EndIf EndFunc ;==>TriggerRedo Hope this inspires someone.
       
       
    • By siawpo
      Hi,
      I'd like to change different colors for different portion of text in same cell of Excel application.
      Neither character length nor cell might not fixed.
      Here's the code I've tried to put together but not manage to pull it off.
      I'm appreciate it for any suggestion, thank you.
      $oExcel = ObjCreate("Excel.Application") With $oExcel ; open new workbook .Visible = True .WorkBooks.Add .ActiveWorkbook.Sheets(1).Select() EndWith $oExcel.Cells.Font.Color = 0x000000 $oExcel.ActiveFont.Color = -16776961 Send ("'I'd like this sentence to be red'") Sleep(100) Send ("{AltDown}{Enter}{AltUp}") Sleep(100) $oExcel.ActiveCell.Selection.Font.Color = 0x000000 Send ("'I like this sentence to be black'") Sleep(100) Send ("{AltDown}{Enter}{AltUp}") Sleep(100) $oExcel.ActiveFont.Color = -16776961 Send ("'I'd like this sentence to be red again'") Sleep(100) Send ("{AltDown}{Enter}{AltUp}") Sleep(100) Send("{ENTER}")  
    • By WindIt
      Hi, 
      I have a set of excel docs 1& 2
      1) In Excel 1 i have a fixed column called dimensionId that contains list of dimensionid's with in between empty cells.
      Here, For each dimesionId, i need to check corresponding columns of L,M,N ,O(senior, mid, junior, student) & check If they contain letter Y (Open excel 2) and if empty ignore,check next.
      I need to loop through the entire column of dimensionId one by one, please help me proceed with the logic.
      2) If letter Y exists, open excel 2 and check if same dimesionId exists in column A.
      New to autoit excel automation, Help me with logic to execute this.
      #include <Excel.au3>
      Global $oExcel = _Excel_Open()
      Global $oWorkbook = _Excel_BookOpen($oExcel, "D:\yta\Trial concept dimensions list.xlsx")
      Local $read1 = _Excel_RangeRead ($oWorkbook,Default,"C3")
      MsgBox(0,"",$read1)
      Attached exce 1 doc.
       
       
      exl1.xlsx exl2.xlsx
×
×
  • Create New...