Jump to content
Sign in to follow this  
XinYoung

Trouble With my Loop Using Excel & IE

Recommended Posts

Hello all,

Preface: Column A is full of courses. Column B is full of usernames. If course (A1) exists, we check to see if username (B1) is enrolled. If user is found, the user is un-enrolled. Then Loop.

I am working on a script that loops through an Excel file and pastes the content from A1 into a textbox in IE, does some stuff, then pastes the content from B1 into a different textbox. Then it loops around until all used rows in columns A and B have been accounted for.

For some reason, column A loops properly but column B doesn't. B1 is pasted over and over again. So, as it loops, B1 is constantly being pasted, first accompanying A1's loop, then A2, and so on.

  • The OpenExcel() func opens the Excel file the user specifies in an earlier function. It's supposed to gather the entire used range of columns A and B.
  • The SearchCourse() func only uses column A, pasting its content into a Search tool in IE. This seems to be working fine.
  • SearchResult() puts "Course Not Found" into column C if the search fails. If the search is successful, however, we move onto...
  • EnterCourse(). This simply gets us to the place where column B's content comes into play.
  • UnenrollNow(). Here, we paste the variable $_userName into a textbox. I don't know why it's always B1 :frantics:
Func OpenExcel()
    If Not WinExists($hWnd) Then
        MsgBox(16, "Window closed", "The Internet Explorer window was closed. Please start over.")
        _Exit()
    Else
        $oExcel = _Excel_Open()
        Global $oWorkbook = _Excel_BookOpen($oExcel, $ChosenFileName, Default, True, True)
        $oExcel.Sheets("CopyCourses").Activate
;~ Get all used cells in columns A and B
        $aSearchItems = _Excel_RangeRead($oWorkbook, 1, $oWorkbook.Sheets("CopyCourses").Usedrange.Columns("A:B"))
;~ Create the $aSearchResult array
        ReDim $aSearchResult[UBound($aSearchItems)]
;~ 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
;~ Column 0
            ConsoleWrite($aSearchItems[$i][0] & @CRLF)
;~ Column 1
            ConsoleWrite($aSearchItems[$i][1] & @CRLF)
            $aSearchResult[$i] = SearchCourse($aSearchItems[$i][0], $aSearchItems[$i][1])
        Next
        _Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "C1")
;~ When the loop is complete, run the Finished function.
        Finished()
    EndIf
EndFunc   ;==>OpenExcel

Func SearchCourse($_sSearchResult, $_userName)
    If Not WinExists($hWnd) Then
        MsgBox(16, "Window closed", "The Internet Explorer window was closed. Please start over.")
        _Exit()
    Else
        _IENavigate($oIE, $urlBBCourseSearch)
        _IELoadWait($oIE)
        Local $oForm = _IEGetObjByName($oIE, "courseManagerFormSearch")
        Local $oSearchString = _IEFormElementGetObjByName($oForm, "courseInfoSearchText")
        _IEFormElementSetValue($oSearchString, $_sSearchResult)
        _IEFormSubmit($oForm)
        _IELoadWait($oIE)
        Local $oBBTable = _IETableGetCollection($oIE, 2)
        $aBBTableData = _IETableWriteToArray($oBBTable)
        Return SearchResult()
    EndIf
EndFunc   ;==>SearchCourse

Func SearchResult()
    If Not WinExists($hWnd) Then
        MsgBox(16, "Window closed", "The Internet Explorer window was closed. Please start over.")
        _Exit()
    Else
        Local $sResult
        $iSearchIndex = _ArraySearch($aBBTableData, "Course ID", 0, 0, 0, 1, 1, 0)
        If $iSearchIndex = -1 Then
            $sResult = "Course Not Found"
            _Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "C1")
        Else
            EnterCourse()
            $sResult = "UnEnrolled!"
            _Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "C1")
        EndIf
        Return $sResult
    EndIf
EndFunc   ;==>SearchResult

Func EnterCourse()
    If Not WinExists($hWnd) Then
        MsgBox(16, "Window closed", "The Internet Explorer window was closed. Please start over.")
        _Exit()
    Else
        Local $clickFail = "DATE CREATED"
        _IELinkClickByIndex($oIE, 34)
        _IELoadWait($oIE)
        $sourceCode = _IEBodyReadHTML($oIE)
        If StringInStr($sourceCode, $clickFail) <> 0 Then
            _IELinkClickByIndex($oIE, 35)
            _IELoadWait($oIE)
        EndIf
        $oLink = _IEGetObjById($oIE, "controlpanel.users.and.groups_groupExpanderLink")
        _IEAction($oLink, "click")
        Sleep(500)
        _IELinkClickByText($oIE, "Users")
        _IELoadWait($oIE)
        $aSearchResult[$i] = UnenrollNow($aSearchItems[$i][0], $aSearchItems[$i][1])
    EndIf
EndFunc   ;==>EnterCourse

Func UnenrollNow($_sourceCourseId, $_userName)
    If Not WinExists($hWnd) Then
        MsgBox(16, "Window closed", "The Internet Explorer window was closed. Please start over.")
        _Exit()
    Else
        Local $UserError = "No users found"
        Local $sResult
        $criteriaUsername = _IEGetObjById($oIE, "userInfoSearchKeyString")
        _IEFormElementOptionSelect($criteriaUsername, 0, 1, 'byIndex')
        $criteriaUsername = _IEGetObjById($oIE, "userInfoSearchOperatorString")
        _IEFormElementOptionSelect($criteriaUsername, 0, 1, 'byIndex')

        ;Paste whats copied from column B into the Username text box.
        Local $oForm = _IEGetObjByName($oIE, "userManagerSearchForm")
        Local $oSearchString = _IEFormElementGetObjByName($oForm, "userInfoSearchText")
        
        ;PROBLEM HERE...
        
        _IEFormElementSetValue($oSearchString, $_userName)
        
        ;^^^^^^ WHY IS $_userName ALWAYS B1 ???
        
        Sleep(1000)
        _IEFormSubmit($oForm)
        _IELoadWait($oIE)

        $sourceCode = _IEBodyReadHTML($oIE)
        If StringInStr($sourceCode, $UserError) <> 0 Then
            $sResult = "User Not Found"
            _Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "C1")
            Return $sResult
        Else
            MsgBox(0, "Unenrollment READY!", "We're ready to unenroll foreal")
            $sResult = "DUN"
            _Excel_RangeWrite($oWorkbook, Default, $aSearchResult, "C1")
            Return $sResult
        EndIf
    EndIf
EndFunc   ;==>UnenrollNow

Please let me know if any further information is needed.

If you see other problems or redundancies in my code, please let me know.

Thank you!

 

Edited by XinYoung

Share this post


Link to post
Share on other sites

Hi Xin, glad to see you're still working.  I will take a look at your case tomorrow.

Share this post


Link to post
Share on other sites

Hard to say just looking at this code, since we don't have access to your web site.  Do I understand right, that the problem is in IE when you set the value ?  Could you show a screen of the problem with the associated DOM ?

Share this post


Link to post
Share on other sites

Sure. Here's the DOM for the inputbox that requires the values from column B in my Excel sheet.

I don't think there's a problem with how I'm manipulating IE though. I think I'm storing the Excel content wrong or looping through Excel wrong.

image.thumb.png.4fcfe0bb900c59665f237ef8804cc251.png

Share this post


Link to post
Share on other sites
$aSearchResult[$i] = UnenrollNow($aSearchItems[$i][0], $aSearchItems[$i][1])

$i is undefined in Func EnterCourse(), I don't even understand how you don't get an error

Share this post


Link to post
Share on other sites
1 hour ago, XinYoung said:

i declare it globally at the beginning of the script...

Remove that, it doesn't make any sense, make your script robust, Any variables inside of a func should come local or from param.  I understand that sometimes, you need to have global vars, but if you want to solve your problems, you should start reducing the bad programming habits.  Sorry from being rude...

ps : Also use : Opt ("MustDeclareVars, 1) at the very beginning of your script.

Edited by Nine

Share this post


Link to post
Share on other sites

OK... You're not rude lol

So, for best practice. how/where should I implement the $i within the EnterCourse() func?

Func EnterCourse()
    If Not WinExists($hWnd) Then
        MsgBox(16, "Window closed", "The Internet Explorer window was closed. Please start over.")
        _Exit()
    Else
        Local $clickFail = "DATE CREATED"
        _IELinkClickByIndex($oIE, 34)
        _IELoadWait($oIE)
        $sourceCode = _IEBodyReadHTML($oIE)
        If StringInStr($sourceCode, $clickFail) <> 0 Then
            _IELinkClickByIndex($oIE, 35)
            _IELoadWait($oIE)
        EndIf
        $oLink = _IEGetObjById($oIE, "controlpanel.users.and.groups_groupExpanderLink")
        _IEAction($oLink, "click")
        Sleep(500)
        _IELinkClickByText($oIE, "Users")
        _IELoadWait($oIE)
        $aSearchResult[$i] = UnenrollNow($aSearchItems[$i][0], $aSearchItems[$i][1])
        
        ;WARNING: $i: possibly used before declaration.
        
    EndIf
EndFunc   ;==>EnterCourse

 

Share this post


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

Do i just throw it in as a local declaration at the beginning?

No, $i comes from another func.  But it is not your only problem.  Lets just take EnterCourse func. 

$hWnd, $oIE, $sourceCode, $aSearchResult, $aSearchItems and $i have all been declared as global vars.  That is really not good. 

$i for example comes from a For loop.  If you read carefully help file, it says that "The variable will be created automatically with Local scope, even when MustDeclareVars is on."  So $i has been declare local in another func.  You cannot access it even if you declare local or global or whatever. Those few functions that you have posted at the beginning needs to be rethink with the best practices :  All vars should be declared locally or passed as function parameters.  If you do that you probably won't have the same number of functions, probably less.
 

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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By mLipok
      In the past there was many questions about how to: "Automatic file upload using without user interaction"

      https://www.autoitscript.com/forum/topic/92907-ie-8-input-namenomfic-typefile-idnomfic/
      https://www.autoitscript.com/forum/topic/116899-cant-automate-input-typefile-tag-in-ie/?tab=comments#comment-815478
      https://www.autoitscript.com/forum/topic/14883-input-typefile/
      https://www.autoitscript.com/forum/topic/188708-how-to-set-the-value-of-an-input-typefile-element/
      https://www.autoitscript.com/forum/topic/91513-how-can-i-auto-set-file-path-for-input-file-in-ie/
      https://www.autoitscript.com/forum/topic/116899-cant-automate-input-typefile-tag-in-ie/
      https://www.autoitscript.com/forum/topic/169190-how-to-script-file-upload-button/
      https://www.autoitscript.com/forum/topic/145327-how-to-deal-with-ie-window-for-upload-a-fileinput-typefile/
      https://www.autoitscript.com/forum/topic/140482-internet-explorer-input-file-problem/
       
      I found solution here: 
      https://stackoverflow.com/questions/33253517/upload-a-file-via-input-input-in-html-form-with-vba
      and:
      https://www.motobit.com/tips/detpg_uploadvbsie/
      And I translate this code to AutoIt3 code:
      ; Upload file using http protocol And multipart/form-data ; v1.01 ; 2001 Antonin Foller, PSTRUH Software Global $oErrorHandler = ObjEvent("AutoIt.Error", _ErrFunc) do_vbsUpload() Func do_vbsUpload() #cs ; We need at least two arguments (File & URL) ConsoleWrite('- ' & @ScriptLineNumber & @CRLF) If $CmdLine[0] < 2 Then InfoEcho() ConsoleWrite('- ' & @ScriptLineNumber & @CRLF) ; Are some required objects missing? If StringInStr(CheckRequirements(), "Error") > 0 Then InfoEcho() ConsoleWrite('- ' & @ScriptLineNumber & @CRLF) Local $s_FileName, $s_DestURL, $s_FieldName $s_FieldName = "FileField" ; Default field name For $i_argCounter = 1 To $CmdLine[0] ConsoleWrite('+ '& $i_argCounter& ' >> ' & $CmdLine[$i_argCounter] & @CRLF) Select Case $i_argCounter = 1 ;~ $s_FileName = $CmdLine[$i_argCounter] $s_FileName = @ScriptFullPath Case $i_argCounter = 2 $s_DestURL = $CmdLine[$i_argCounter] Case $i_argCounter = 3 $s_FieldName = $CmdLine[$i_argCounter] EndSelect Next UploadFile($s_DestURL, $s_FileName, $s_FieldName) #ce UploadFile('http://www.dobeash.com/test.html', @ScriptFullPath, 'fileExample') EndFunc ;==>do_vbsUpload ; ******************* upload - begin ; Upload file using input type=file Func UploadFile($s_DestURL, $s_FileName, $s_FieldName) ; Boundary of fields. ; Be sure this string is Not In the source file Const $Boundary = "---------------------------0123456789012" ; Get source file As a binary data. Local $d_FileContents = GetFile($s_FileName) ; Build multipart/form-data document Local $s_FormData = BuildFormData($d_FileContents, $Boundary, $s_FileName, $s_FieldName) ; Post the data To the destination URL IEPostBinaryRequest($s_DestURL, $s_FormData, $Boundary) EndFunc ;==>UploadFile ; Build multipart/form-data document with file contents And header info Func BuildFormData($d_FileContents, $Boundary, $s_FileName, $s_FieldName) Const $s_ContentType = "application/upload" ; The two parts around file contents In the multipart-form data. Local $s_Pre = "--" & $Boundary & @CRLF & mpFields($s_FieldName, $s_FileName, $s_ContentType) Local $s_Po = @CRLF & "--" & $Boundary & "--" & @CRLF ; Build form data using recordset binary field Const $i_adLongVarBinary = 205 Local $oRS = ObjCreate("ADODB.Recordset") ; https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/append-method-ado?view=sql-server-ver15 $oRS.Fields.Append("b", $i_adLongVarBinary, StringLen($s_Pre) + BinaryLen($d_FileContents) + StringLen($s_Po)) $oRS.Open() $oRS.AddNew() ; Convert Pre string value To a binary data Local $i_LenData = StringLen($s_Pre) $oRS("b").AppendChunk(StringToMB($s_Pre) & StringToBinary(Chr(0))) $s_Pre = $oRS("b").GetChunk($i_LenData) $oRS("b") = "" ; Convert Po string value To a binary data $i_LenData = StringLen($s_Po) $oRS("b").AppendChunk(StringToMB($s_Po) & StringToBinary(Chr(0))) $s_Po = $oRS("b").GetChunk($i_LenData) $oRS("b") = "" ; Join Pre & $d_FileContents & Po binary data $oRS("b").AppendChunk($s_Pre) $oRS("b").AppendChunk($d_FileContents) $oRS("b").AppendChunk($s_Po) $oRS.Update() Local $s_FormData = $oRS("b") $oRS.Close() Return $s_FormData EndFunc ;==>BuildFormData ; sends multipart/form-data To the URL using IE Func IEPostBinaryRequest($s_URL, $s_FormData, $Boundary) ; Create InternetExplorer Local $oIE = ObjCreate("InternetExplorer.Application") ; You can uncoment Next line To see form results $oIE.Visible = True ; Send the form data To $s_URL As POST multipart/form-data request $oIE.Navigate($s_URL, '', '', $s_FormData, _ "Content-Type: multipart/form-data; boundary=" & $Boundary & @CRLF) While $oIE.Busy Wait(1, "Upload To " & $s_URL) WEnd ; Get a result of the script which has received upload ;~ On Error Resume Next Local $s_IE_InnerHTML = $oIE.Document.body.innerHTML MsgBox(0, 'TEST #' & @CRLF & @ScriptLineNumber, $s_IE_InnerHTML) $oIE.Quit() Return $s_IE_InnerHTML EndFunc ;==>IEPostBinaryRequest ; Infrormations In form field header. Func mpFields($s_FieldName, $s_FileName, $s_ContentType) Local $s_MPTemplate = _ ; template For multipart header 'Content-Disposition: form-data; name="{field}";' & _ 'FileName="{file}"' & @CRLF & _ 'Content-Type: {ct}' & @CRLF & @CRLF & _ '' Local $s_Out $s_Out = StringReplace($s_MPTemplate, "{field}", $s_FieldName) $s_Out = StringReplace($s_Out, "{file}", $s_FileName) $s_Out = StringReplace($s_Out, "{ct}", $s_ContentType) Return $s_Out EndFunc ;==>mpFields Func Wait($i_Seconds, $s_Message) MsgBox(64, '', $s_Message, $i_Seconds) EndFunc ;==>Wait ; Returns file contents As a binary data Func GetFile($s_FileName) Local $oStream = ObjCreate("ADODB.Stream") $oStream.Type = 1 ; Binary $oStream.Open() $oStream.LoadFromFile($s_FileName) Local $d_GetFile = $oStream.Read() $oStream.Close() Return $d_GetFile EndFunc ;==>GetFile ; Converts OLE string To multibyte string Func StringToMB($S) Local $I, $B For $I = 1 To StringLen($S) $B &= StringToBinary(Asc(StringMid($S, $I, 1))) Next Return $B EndFunc ;==>StringToMB ; ******************* upload - end ; ******************* Support ; Basic script info Func InfoEcho() Local $sMsg = _ "Upload file using http And multipart/form-data" & @CRLF & _ "Copyright (C) 2001 Antonin Foller, PSTRUH Software" & @CRLF & _ "use" & @CRLF & _ "[cscript|wscript] fupload.vbs file $s_URL [fieldname]" & @CRLF & _ " file ... Local file To upload" & @CRLF & _ " $s_URL ... $s_URL which can accept uploaded data" & @CRLF & _ " fieldname ... Name of the source form field." & @CRLF & _ @CRLF & CheckRequirements() & @CRLF & _ "" ConsoleWrite('! ' & $sMsg & @CRLF) EndFunc ;==>InfoEcho ; Checks If all of required objects are installed Func CheckRequirements() Local $sMsg = _ "This script requires some objects installed To run properly." & @CRLF & _ CheckOneObject("ADODB.Recordset") & @CRLF & _ CheckOneObject("ADODB.Stream") & @CRLF & _ CheckOneObject("InternetExplorer.Application") & @CRLF & _ "" Return $sMsg ; $sMsgBox $sMsg EndFunc ;==>CheckRequirements ; Checks If the one object is installed. Func CheckOneObject($sClassName) Local $sMsg ObjCreate($sClassName) If @error = 0 Then $sMsg = "OK" Else $sMsg = "Error:" & @error EndIf Return $sClassName & " - " & $sMsg EndFunc ;==>CheckOneObject ; ******************* Support - end ; User's COM error function. Will be called if COM error occurs Func _ErrFunc(ByRef $oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFunc  
      But I miss something and the code not works as intendend.
      Please join and contribute, in solving this issue, as this will be handy for entire community.
      @mLipok
       
      btw.
      I think that this may be realated to ChrB() which I simply translate to StringToBinary()
      Especialy this :
      StringToBinary(Chr(0))) could be the main issue.
      But for now I'm tired and going to sleep.
      Hope maybe tomorrow somebody solve this issue.
       
    • By Cristin
      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.

      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
    • 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 Deshanur
      Am trying to automate injecting credential on the login form for all kind of Web application for IE. I know how to identify the form name by viewing the source code and using the method - _IEFormGetObjByName($ie, $form_Name).
      I would like to know how to identify or get the form object for the web app where there is no form name tag for example below, for the is I have used - _IEFormGetCollection($ie, 0) to get the form object.
      My Question is does it work for all kind of application "_IEFormGetCollection($ie, 0)" how to identify Index value? is it always 0? is there any better solution?
      The final solution am looking for is find out form object, get the username, password field and inject credential and submit the form.
      How to find out index value? for the forms which does not have form name field.
      $login_form = _IEFormGetCollection($ie, 0) $email_field = _IEFormElementGetObjByName($login_form, $form_UserName) $pass_field = _IEFormElementGetObjByName($login_form, $form_password) $login_button = _IEFormElementGetObjByName($login_form, $form_submitbutton) _IEFormElementSetValue($email_field, $CmdLine[2]) _IEFormElementSetValue($pass_field, $CmdLine[3]) ControlSend($hwnd, "", "[CLASS:Internet Explorer_Server; INSTANCE:1]","{Enter}") OR This works fine if the form has form name. $login_form = _IEFormGetObjByName($ie, $form_Name) $email_field = _IEFormElementGetObjByName($login_form, $form_UserName) $pass_field = _IEFormElementGetObjByName($login_form, $form_password) $login_button = _IEFormElementGetObjByName($login_form, $form_submitbutton) _IEFormElementSetValue($email_field, $CmdLine[2]) _IEFormElementSetValue($pass_field, $CmdLine[3]) ControlSend($hwnd, "", "[CLASS:Internet Explorer_Server; INSTANCE:1]","{Enter}")
    • 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.
       
       
×
×
  • Create New...