Jump to content

Do...Until Excel sheet has no more data?


Recommended Posts

Why hello there! :D

I have a script reading an Excel sheet (currently only looking at A1), copying the data in that cell, and then searching for it in a Website's search tool. Then it does some stuff if it actually finds something.

After that, I need it to go back to the Excel sheet, write "yes" into column B if the search was good -- "no" if no results were found, then go down to A2 and do the whole thing all over again until column A has nothing left.

:frantics: I really suck at loops and have a hard time grasping how it works. Any help or guidance is really appreciated!

 

SearchCourse()

;~  Now that were logged in, navigate to the course search page.
Func SearchCourse()
    _IENavigate($oIE, $urlBBCourseSearch)

;~  Change the search criteria to "Course ID"
    _bbCourseSearchCategoryChange("Course ID")

;~  Open the selected Excel file
    Local $oAppl = _Excel_Open()
    Local $oWorkbook = _Excel_BookOpen($oAppl, $ChosenFileName, Default, Default, True)

;~ Copy whats in the first cell (A1)
    _Excel_RangeCopyPaste($oWorkbook.Worksheets(1), "A1")
    Global $WhatsCopied = ClipGet()

;~ Paste whats copied into the search text box and click submit
    Local $oForm = _IEGetObjByName($oIE, "courseManagerFormSearch")
    Local $oSearchString = _IEFormElementGetObjByName($oForm, "courseInfoSearchText")
    _IEFormElementSetValue($oSearchString, $WhatsCopied)
    _IEFormSubmit($oForm)

;~ Lets see what we got from the search
    Local $oBBTable = _IETableGetCollection($oIE, 2)
    Global $aBBTableData = _IETableWriteToArray($oBBTable)
    _ArrayDisplay($aBBTableData)

    DeleteCourseBegin()

EndFunc   ;==>SearchCourse

;~ OK, we logged in and we searched for a course. Lets delete it!
Func DeleteCourseBegin()
    $iSearchIndex = _ArraySearch($aBBTableData, "Course ID", 0, 0, 0, 1, 1, 0)
    
;~  If the course was not found, do this.
    If $iSearchIndex = -1 Then
        MsgBox(4096, "Search Error", "Item not found")
;~  Now go back to the Excel sheet and search for the next one....?

;~ If the course was found, begin the deletion process.
    Else
        MsgBox(4096, "Search Success", $aBBTableData[$iSearchIndex][0] & " = " & $aBBTableData[$iSearchIndex][1])
        DeleteCourseNow()
    EndIf
EndFunc   ;==>DeleteCourseBegin

;~ The course search was successful. Delete the course now.
Func DeleteCourseNow()
;~ Click the checkbox located beside the course that has been found.
    Local $CheckBox = _IEGetObjByName($oIE, "ckbox")
    _IEAction($CheckBox, "click")
    _IELoadWait($oIE)

;~ Click the Delete button.
    _IELinkGetCollection($oIE)
    Local $oLinks = _IELinkGetCollection($oIE)
    For $oLink In $oLinks
        If $oLink.href = "javascript:validateRemove();" Then
            _IEAction($oLink, "click")
            ExitLoop
        EndIf
    Next

;~  Click the "Delete course, including all of its files" radio button.
    Local $RadioButton = _IEGetObjById($oIE, "removeAllFiles_t")
    _IEAction($RadioButton, "click")
    _IELoadWait($oIE)

;~ Click the "Submit" button
    Local $Submit = _IEGetObjByName($oIE, "bottom_Submit")
    _IEAction($Submit, "click")
    _IELoadWait($oIE)

;~  Now go back to the Excel sheet and search for the next one....?

EndFunc   ;==>DeleteCourseNow

 

 

Edited by XinYoung
Fixed some comments in the code
Link to post
Share on other sites

If you do this after you make your workbook object, you will get the size of the excel workbook (know what the last line of the excel file will be).

#include <array.au3>

$array = _Excel_RangeRead($oWorkbook)
$size = Ubound($array)

Give adding in a loop a try now that you know the size. If you are still struggling with it, let us know!

Edited by Davidowicza
Grammar
Link to post
Share on other sites
  • Moderators

@XinYoung You can do this easily with _Excel_RangeWrite. Something like this should get you started:

#include <Excel.au3>

Local $oExcel = _Excel_Open()
Local $oWorkbook = _Excel_BookOpen($oExcel, @DesktopDir & "\Test1.xlsx")
Local $oRange = _Excel_RangeRead($oWorkbook, Default, Default)

For $a = 1 To UBound($oRange)
    ;Do other Stuff
    _Excel_RangeWrite($oWorkbook, Default, "This is cell B" & $a, "B" & $a)
Next

_Excel_BookClose($oWorkbook)
_Excel_Close($oExcel)

If your columns have headers, you'll have to adjust by one.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to post
Share on other sites

It would be faster to just grab all of A:A into an array and loop through the results and create a second array to hold the "Yes/No" here is an example untested:

#include <Array.au3>
#include <Excel.au3>
Global $sChosenFileName = "Filename.xlsx"
Global $aBBTableData
Global $oExcel = _Excel_Open()
Global $oWorkbook = _Excel_BookOpen($oExcel, $sChosenFileName)
;~ Get all used cells in column A:A
Global $aSearchItems = _Excel_RangeRead($oWorkbook, Default, $oWorkbook.ActiveSheet.Usedrange.Columns("A:A"))
;~ Duplicate the $aSearchItems Array 
Global $aSearchResult = $aSearchItems
;~ Loop through $aSearchItems
;~ Since Excel_RangeRead returns a 0-based Array and since we only captured one column it is a 1 dimension array
;~ Loop through the array starting at 0 until the end of the array which is (Ubound($aSearchItems) - 1)
For $i = 0 To UBound($aSearchItems) - 1
    $aSearchResult[$i] = SearchCourse($aSearchItems[$i])
Next
_ArrayDisplay($aSearchItems, "Search Items")
_ArrayDisplay($aSearchResult, "Search Results")
;~ Paste the results back to Excel in column B1
_Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "B1")

Func SearchCourse($_sSearch)
    _IENavigate($oIE, $urlBBCourseSearch)

;~  Change the search criteria to "Course ID"
    _bbCourseSearchCategoryChange("Course ID")

;~ Paste whats copied into the search text box and click submit
    Local $oForm = _IEGetObjByName($oIE, "courseManagerFormSearch")
    Local $oSearchString = _IEFormElementGetObjByName($oForm, "courseInfoSearchText")
    _IEFormElementSetValue($oSearchString, $_sSearch)
    _IEFormSubmit($oForm)

;~ Lets see what we got from the search
    Local $oBBTable = _IETableGetCollection($oIE, 2)
    $aBBTableData = _IETableWriteToArray($oBBTable)
    _ArrayDisplay($aBBTableData)

    DeleteCourseBegin()

EndFunc   ;==>SearchCourse

;~ OK, we logged in and we searched for a course. Lets delete it!
Func DeleteCourseBegin()
    $iSearchIndex = _ArraySearch($aBBTableData, "Course ID", 0, 0, 0, 1, 1, 0)
    
;~  If the course was not found, do this.
    If $iSearchIndex = -1 Then
        MsgBox(4096, "Search Error", "Item not found")
        $sResult = "No"
;~  Now go back to the Excel sheet and search for the next one....?

;~ If the course was found, begin the deletion process.
    Else
        MsgBox(4096, "Search Success", $aBBTableData[$iSearchIndex][0] & " = " & $aBBTableData[$iSearchIndex][1])
        DeleteCourseNow()
        $sResult = "Yes"
    EndIf
    Return $sResult
EndFunc   ;==>DeleteCourseBegin

;~ The course search was successful. Delete the course now.
Func DeleteCourseNow()
;~ Click the checkbox located beside the course that has been found.
    Local $CheckBox = _IEGetObjByName($oIE, "ckbox")
    _IEAction($CheckBox, "click")
    _IELoadWait($oIE)

;~ Click the Delete button.
    _IELinkGetCollection($oIE)
    Local $oLinks = _IELinkGetCollection($oIE)
    For $oLink In $oLinks
        If $oLink.href = "javascript:validateRemove();" Then
            _IEAction($oLink, "click")
            ExitLoop
        EndIf
    Next

;~  Click the "Delete course, including all of its files" radio button.
    Local $RadioButton = _IEGetObjById($oIE, "removeAllFiles_t")
    _IEAction($RadioButton, "click")
    _IELoadWait($oIE)

;~ Click the "Submit" button
    Local $Submit = _IEGetObjByName($oIE, "bottom_Submit")
    _IEAction($Submit, "click")
    _IELoadWait($oIE)
;~  Now go back to the Excel sheet and search for the next one....?

EndFunc   ;==>DeleteCourseNow

 

Edited by Subz
Link to post
Share on other sites

OK, I tried implementing it but I'm getting an error: SearchCourse() called by a previous line with 0 arg(s)

Because of the way I call upon the func...?

 

OpenExcel()

Func OpenExcel()
    Global $aBBTableData
    Global $oExcel = _Excel_Open()
    Global $oWorkbook = _Excel_BookOpen($oExcel, $ChosenFileName, Default, Default, True)
;~ Get all used cells in column A:A
    Global $aSearchItems = _Excel_RangeRead($oWorkbook, Default, $oWorkbook.ActiveSheet.Usedrange.Columns("A:A"))
;~ Duplicate the $aSearchItems Array
    Global $aSearchResult = $aSearchItems
;~ Loop through $aSearchItems
;~ Since Excel_RangeRead returns a 0-based Array and since we only captured one column it is a 1 dimension array
;~ Loop through the array starting at 0 until the end of the array which is (Ubound($aSearchItems) - 1)
    For $i = 0 To UBound($aSearchItems) - 1
        $aSearchResult[$i] = SearchCourse($aSearchItems[$i])
    Next
    _ArrayDisplay($aSearchItems, "Search Items")
    _ArrayDisplay($aSearchResult, "Search Results")
;~ Paste the results back to Excel in column B1
    _Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "B1")

    SearchCourse()

EndFunc   ;==>OpenExcel


;~  Now that were logged in, navigate to the course search page.
Func SearchCourse($aSearchResult)
    _IENavigate($oIE, $urlBBCourseSearch)

    ;~  Change the search criteria to "Course ID"
    _bbCourseSearchCategoryChange("Course ID")

;~ Paste whats copied into the search text box and click submit
    Local $oForm = _IEGetObjByName($oIE, "courseManagerFormSearch")
    Local $oSearchString = _IEFormElementGetObjByName($oForm, "courseInfoSearchText")
    _IEFormElementSetValue($oSearchString, $aSearchResult)
    _IEFormSubmit($oForm)

;~ Lets see what we got from the search
    Local $oBBTable = _IETableGetCollection($oIE, 2)
    $aBBTableData = _IETableWriteToArray($oBBTable)
    _ArrayDisplay($aBBTableData)

    DeleteCourseBegin()

EndFunc   ;==>SearchCourse



;~ OK, we logged in and we searched for a course. Lets delete it!
Func DeleteCourseBegin()
    $iSearchIndex = _ArraySearch($aBBTableData, "Course ID", 0, 0, 0, 1, 1, 0)

;~  If the course was not found, do this.
    If $iSearchIndex = -1 Then
        MsgBox(4096, "Search Error", "Item not found")
        $sResult = "No"
;~  Now go back to the Excel sheet and search for the next one....?

;~ If the course was found, begin the deletion process.
    Else
        $aSearchResult
        MsgBox(4096, "Search Success", $aBBTableData[$iSearchIndex][0] & " = " & $aBBTableData[$iSearchIndex][1])
        DeleteCourseNow()
        $sResult = "Yes"
    EndIf
    Return $sResult
EndFunc   ;==>DeleteCourseBegin

;~ The course search was successful. Delete the course now.
Func DeleteCourseNow()
;~ Click the checkbox located beside the course that has been found.
    Local $CheckBox = _IEGetObjByName($oIE, "ckbox")
    _IEAction($CheckBox, "click")
    _IELoadWait($oIE)

;~ Click the Delete button.
    _IELinkGetCollection($oIE)
    Local $oLinks = _IELinkGetCollection($oIE)
    For $oLink In $oLinks
        If $oLink.href = "javascript:validateRemove();" Then
            _IEAction($oLink, "click")
            ExitLoop
        EndIf
    Next

;~  Click the "Delete course, including all of its files" radio button.
    Local $RadioButton = _IEGetObjById($oIE, "removeAllFiles_t")
    _IEAction($RadioButton, "click")
    _IELoadWait($oIE)

;~ Click the "Submit" button
    Local $Submit = _IEGetObjByName($oIE, "bottom_Submit")
    _IEAction($Submit, "click")
    _IELoadWait($oIE)
;~  Now go back to the Excel sheet and search for the next one....?

EndFunc   ;==>DeleteCourseNow

 

So, is this being caused by how I have everything residing within a Func? Because at the end of each func, I call upon another one. Is that not a good way to go about it? :huh2:

I can't do something like Func SearchCourse($aSearchResult) this way?

 

Link to post
Share on other sites

OhHhHHhHHHh my bad! I get it. It was already there and I put it in again with 0 arg. amirite?

Alright that error is gone! :lol:

Now I'm getting Statement cannot be just an expression regarding $aSearchResult in the Else...

;~ OK, we logged in and we searched for a course. Lets delete it!
Func DeleteCourseBegin()
    $iSearchIndex = _ArraySearch($aBBTableData, "Course ID", 0, 0, 0, 1, 1, 0)

;~  If the course was not found, do this.
    If $iSearchIndex = -1 Then
        MsgBox(4096, "Search Error", "Item not found")
        $sResult = "No"
;~  Now go back to the Excel sheet and search for the next one....?

;~ If the course was found, begin the deletion process.
    Else
        $aSearchResult
        MsgBox(4096, "Search Success", $aBBTableData[$iSearchIndex][0] & " = " & $aBBTableData[$iSearchIndex][1])
        DeleteCourseNow()
        $sResult = "Yes"
    EndIf
    Return $sResult
EndFunc   ;==>DeleteCourseBegin

 

Link to post
Share on other sites

Hmmm, still getting the same error

;~ OK, we logged in and we searched for a course. Lets delete it!
Func DeleteCourseBegin()
    Local $sResult
    $iSearchIndex = _ArraySearch($aBBTableData, "Course ID", 0, 0, 0, 1, 1, 0)

;~  If the course was not found, do this.
    If $iSearchIndex = -1 Then
        MsgBox(4096, "Search Error", "Item not found")
        $sResult = "No"
;~  Now go back to the Excel sheet and search for the next one....?

;~ If the course was found, begin the deletion process.
    Else
        $aSearchResult
        MsgBox(4096, "Search Success", $aBBTableData[$iSearchIndex][0] & " = " & $aBBTableData[$iSearchIndex][1])
        DeleteCourseNow()
        $sResult = "Yes"
    EndIf
    Return $sResult
EndFunc   ;==>DeleteCourseBegin

image.thumb.png.524dd4e53ca41f00296096e748043913.png

Link to post
Share on other sites

Sorry a bit difficult to write code without testing, but you should be able to fix this by changing the SearchCourse(..) function, adding Return DeleteCourseBegin

;~  Now that were logged in, navigate to the course search page.
Func SearchCourse($_sSearchItem)
    _IENavigate($oIE, $urlBBCourseSearch)

    ;~  Change the search criteria to "Course ID"
    _bbCourseSearchCategoryChange("Course ID")

;~ Paste whats copied into the search text box and click submit
    Local $oForm = _IEGetObjByName($oIE, "courseManagerFormSearch")
    Local $oSearchString = _IEFormElementGetObjByName($oForm, "courseInfoSearchText")
    _IEFormElementSetValue($oSearchString, $_sSearchItem)
    _IEFormSubmit($oForm)

;~ Lets see what we got from the search
    Local $oBBTable = _IETableGetCollection($oIE, 2)
    $aBBTableData = _IETableWriteToArray($oBBTable)
    _ArrayDisplay($aBBTableData)

    Return DeleteCourseBegin()
EndFunc   ;==>SearchCourse

 

Link to post
Share on other sites

Hey, um, what do I change here to make it always target a sheet named "DeleteCourses" in my Excel workbook? Sometimes the file was saved on a different sheet, which causes the wrong sheet to be Active.

Func OpenExcel()
    Global $aBBTableData
    Global $oExcel = _Excel_Open()
    Global $oWorkbook = _Excel_BookOpen($oExcel, $ChosenFileName, Default, Default, True)
;~ Get all used cells in column A:A
    Global $aSearchItems = _Excel_RangeRead($oWorkbook, 1, $oWorkbook.ActiveSheet.Usedrange.Columns("A:A"))
;~ Duplicate the $aSearchItems Array
    Global $aSearchResult = $aSearchItems
;~ Loop through $aSearchItems
;~ Since Excel_RangeRead returns a 0-based Array and since we only captured one column it is a 1 dimension array
;~ Loop through the array starting at 0 until the end of the array which is (Ubound($aSearchItems) - 1)
    For $i = 0 To UBound($aSearchItems) - 1
        $aSearchResult[$i] = SearchCourse($aSearchItems[$i])
    Next
    _Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "B1")
    Finished()
EndFunc   ;==>OpenExcel

Thanks again

Link to post
Share on other sites
56 minutes ago, XinYoung said:

what do I change here to make it always target a sheet named "DeleteCourses"

 

Assuming that the sheet actually exists, the following line will make sure that the sheet is active:

$oExcel.Sheets("DeleteCourses").Activate

 

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 goku200
      I have an Autoit script that lists files from a folder into an array list. Is there a way to separate the filenames by an underscore and include the id, version, name and date into separate columns in Excel.
      Example of filename:
      12345_v1.0_TEST Name [12345]_01.01.2022.html
      12345 would be in one column
      v1.0 would be in another column
      TEST Name [12345] would be in another column
      01.01.2022 would be in another column
      .html would be in another column
      Note: filenames always change each day.
      Here is my code that lists the files into column C and then writes the column Headers into Column D, E, F, G. Just need some help with separating them into columns by the _ delimiter
       
    • By SkysLastChance
      I am having a issue of whenever I try to _Excel_RangeWrite a formula that references another workbook I am getting an error @4 and @extended -2147352567

      #include <Excel.au3> #include <MsgBoxConstants.au3> Local $oExcel = _Excel_Open() Local $oWorkbook = _Excel_BookNew($oExcel) _Excel_RangeWrite($oWorkBook,Default,"=IF(D2=D1,"",VLOOKUP(D2,'J:\Temporary Files\FolderName\FileName.xlsx'!$A:$B,2,0))","W2",False) If @error Then Exit MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_RangeWrite Example 1", "Error writing to worksheet." & @CRLF & "@error = " & @error & ", @extended = " & @extended) MsgBox($MB_SYSTEMMODAL, "Excel UDF: _Excel_RangeWrite Example 1", "String successfully written.") I am not a 100% sure, but I am guessing this is because I have "" and '' in the formula. However, I am not sure how this can best be resolved. 
       
       
    • By SkysLastChance
      I am trying to autofill a range. I am getting stuck and I don't understand what I am doing wrong. 
      My goal is to auto fill some formulas that are next to a pivot table in columns A-C. 
      _Excel_RangeWrite($oNewWorkBook,Default,"2000","D3") _Excel_RangeWrite($oNewWorkBook,Default,"=(B3-D3)","E3") _Excel_RangeWrite($oNewWorkBook,Default,"100","F3") _Excel_RangeWrite($oNewWorkBook,Default,"=(C3-F3)","G3") $oNewWorkbook.ActiveSheet.Range("D3:G3").Select With $oNewWorkbook .Selection.AutoFill(.Range("D3:G77"),0) EndWith The data is not auto filling. 
      Hoping someone can point me in the right direction. 
    • By Rskm
      Hi, I have 5 notepad files with lot of data in each of it. The data are arranged in lines and i wish to get it pasted/copied into excel.  Say, i need to read notepad1 and paste the contents into sheet1 of excel and notepad2 to sheet2 and so on.  If i read the notepad and paste it line by line, it is taking lot of time.  Is there a way by which i can paste the whole of notepad file into excel sheet(and get it pasted line by line as shown in the attached excel), instead of using code to write it line by line?.. I was using Filewriteline(data, line i) initially to write to excel.  The 'i' value was incremented with for loop and the excel was updated, but this takes lot of time.  The expected excel format is attached here.  any help is appreciated.  thanks
      Tmp.xls
    • By mmoalem
      Hi all - I have created a simple script that turn on cctv software (contacam)  when my phone does not ping back (when I'm out of range of home network)
      #include <MsgBoxConstants.au3> $iPing = 0 For $i = 5 To 1 Step -1 ; this 5 loops cycle is just for testing - please ignnore - when complete it will be an endless loop Example() Sleep(120000) Next Func Example() ; Ping the phone. $iPing = Ping("192.168.1.102") If $iPing Then ; If a value greater than 0 was returned then turn off camera. _endCCTV() Else _startCCTV() ; If a value of 0 was returned then turn on camera. EndIf EndFunc ;==>Example Func _startCCTV() ShellExecute("C:\contacam capture\FJ Camera\CAMERA.bat", "on") Sleep(10000) ShellExecute("C:\contacam capture\FJ Camera\CAMERA_REC_SENSITIVITY.bat", "50") EndFunc Func _endCCTV() ShellExecute("C:\contacam capture\FJ Camera\CAMERA_REC_SENSITIVITY.bat", "0") Sleep(10000) ShellExecute("C:\contacam capture\FJ Camera\CAMERA.bat", "off") EndFunc  
       
      the problem I have is that in this format the script run the bat file that turn on the camera (or off) everytime the ping runs but obviously once the ping returns 0 and the camera starts I only want to run the bat on ping NOT 0 (turn off camera) 
      any ideas/advice?
×
×
  • Create New...