Disable Alert message of a webpage using VBA code - vba

I am opening a webpage using VBA code which contains form where data will be filled by user. I have excel file which contains data. I write VBA code that read the data from excel and put it on webpage. After filling information on webpage I click on Save button. All this work I had done using VBA code so that it can be done automatically. I have 500 users data hence I run the loop 500 times. All it done fines.
Only one problem come and it is that after filling data in webpage form when I click on save button a popup message comes "Your data saved successfully". It has "OK" button. Now my program stops here and need user intervention to manually click on "OK" button.
Is there any way using VBA code by which we can stop this popup message box, so that manual intervention is no longer required?
I read the webpage and Javascript written for webpage also. I found that when Save button is clicked a function called savedetails() . Inside this function a alert() function is there. Sample code here
function saveDetails()
{
/* get details of member*/
---
---
---
---
---
if (xml.status == 200 || window.location.href.indexOf("http") == -1) {
var successCode = "";
alert("Data Saved Successfully");
var tes = xml.responseText;
/* if (successCode == '1') { */
document.webDataForm.submit();
remove_popup();
};
}
VBA Code For Each htmlInput In htmlColl
If Trim(htmlInput.ID) = "btn" Then
If Trim(htmlInput.Name) = "btnfinal" Then
htmlInput.Click 'After this "Data Saved Successfully popup message comes and program need user intervention
temp = htmlInput.getAttribute("onClick")
MsgBox temp
'IE.document.getElementById("clearRelItems").removeAttribute ("o n C l i c k")
'Call iedoc.parentWindow.execScript("window.confirm = function saveBankDetails() {return true}", "JavaScript") // Not worked
'htmlInput.removeAttribute ("onClick") //Not worked
'htmlInput.setAttribute "onClick", "return TRUE" //Not worked
'Application.SendKeys "{ENTER}", True // Not worked
Exit For
End If
End If
Next htmlInput

You could try wrapping the line with the Application.DisplayAlerts function that produces the display box you don't want;
eg.
If Trim(htmlInput.ID) = "btn" Then
If Trim(htmlInput.Name) = "btnfinal" Then
Application.DisplayAlerts = False
htmlInput.Click
Application.DisplayAlerts = True
.... Further Code

I had this problem and the only way I could solve it was by writing a vb script that identifies the pop up and closes it...
After that, you just need to call it from your vba code.

Related

Multipage error: The object invoked has disconnected from its clients

So I've probably spent the last week researching/trying to fix this annoying error but to no avail. Here's what I'm trying to do and the error I'm getting:
I have a userform that contains 12 multipage pages and to access each one I have coded previous/next buttons. Now, One of these pages is disabled through properties to hide from the user, that is until a specific checkbox is clicked. When it's clicked, the page is enabled, and the user is now able to view this page as well as all the others. when the checkbox is clicked again (making it false and no longer true), the page hides from the user's sight. This is basically what I'm trying to accomplish. The pages are like so:
page1, page2, page3, page4, "page5", page6, etc.
As you can see, page5 is what is being disabled/enabled. Now also, something important to note, I've made the userform to appear before the workbook is actually visible using this:
Private Sub Workbook_Open()
Application.ScreenUpdating = False
ThisWorkbook.Application.Visible = False
OpeningWindow.Show
Windows(ThisWorkbook.Name).Visible = True
Application.Visible = True
Application.ScreenUpdating = True
End Sub
This I would like to avoid changing because it's vital that the userform appear first before the workbook because the workbook is acting as the storage/database for everything that is being typed in the userform using this multipage system. Now when I run the userform through VBA and test out this function "checkbox_click Enables/Disables multipage page", it works no problem. When I attempt to open it (as if you were starting up excel without anything opened) everything works fine, until I click the checkbox in question to enable the multipage to make it visible. This is where I'm getting the error "The object invoked has disconnected from it's clients". Now I've tried some other things out to see if I could get the same result:
Made the multipage page visible = False instead of Enabled = false.
Result: This somewhat works, however when attempting to click the previous button to go back a page (Page6 to Page5) when Page5 is visible = False, The previous button doesn't respond, as if it knows that Page5 is there even though it's invisible.
Anyway, to wrap things up, I would like to ask the community here if anyone knows exactly why, from the code I've provided below that is responsible for this "page enable/disable feature", I'm getting this object invoked has disconnected error and if there's a way to fix it.
Private Sub CheckBox119_Click()
If CheckBox119.Value = True Then
Me.MultiPage1.Pages(5).Enabled = True
CheckBox138.Value = True
Label309.Visible = True
Else
Me.MultiPage1.Pages(5).Enabled = False
CheckBox138.Value = False
Label309.Visible = False
End If
End Sub
CheckBox138 btw is located on Page5 and is there if the user wishes to click it to disable page5 and Jump to Page4, which is this code:
Private Sub CheckBox138_Click()
If CheckBox138.Value = False Then
MultiPage1.Value = 4
CheckBox119.Value = False
Label309.Visible = False
End If
End Sub
Also, I'm relatively new to coding in VBA, but I'm always ready to learn.
After some playing around, I believe I figured out what the problem was. The checkbox138 in the disabled page was the culprit. By deleting the code Private sub checkbox138_click(), it works now. I'm not entirely sure why this is the case (so someone with more knowledge may be able to explain) But When checkbox119 is clicked, checkbox138 is suppose to turn true being that's what the initial code expressed. However, even though making checkbox119 true is suppose to enable the disabled page followed by making checkbox138 true, there seems to be a hiccup. It seems checkbox138 is thinking the disabled page is still disabled (even though checkbox119 is suppose to enable it) therefore making the checkbox138 hidden.

VBA Update Document after sending a form

I'm trying to read out something from a website using an excel vba macro.
(MS Office 365/Windows 10/IE Explorer 11)
I navigate to the webpage. This page is a form where I have to confirm a checkbox and press a button. This works all fine, but how can I read out the webpage after the form has been sended? My code:
Dim objbrowser As New InternetExplorer
objbrowser.Navigate ("http://www.formdemo.htm")
GoSub SubWaitForIE 'I put the wait for IE loop into a sub
set docFile = objbrowser.Document
vCheckbox = docFile.getElementsByName("agreecheck"): vCheckbox.Click
docFile.getElementById("sendbutton").Click
GoSub SubWaitForIE
At this point, the form is transmitted, the result page is loaded.
But how do I get the resultpage in to an object like in
set docFile = objbrowser.Document
again??

VBA-Excel: Filling forms in an IE Window

I'm hoping someone can help. I'm trying to speed up the process of filling a webform that must be completed dozens or hundreds of times with information stored in excel.
To do this, I need one button to open an IE window and navigate to a certain website's login page (I've figured this bit out). The user can then log in and navigate to the form that needs to be filled. Then, I'd like the user to be able to return to the excel page, click another button, which will automatically fill several drop downs and text boxes.
Within Excel, I already have some code to allow the user to search for the particular set of information that needs to go to the form, so all they should have to do is click the button to transfer it over. The first bit of the code is just this:
Public IE As Object
Public Sub OpenIE()
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate "loginpage url"
End Sub
Where I'm having trouble, however, is having a different function access the same IE window once the user has logged in and navigated to the form. Right now I've got this:
Sub FillMacro()
Dim sh As Object, oWin As Object
Set sh = CreateObject("Shell.Application")
For Each oWin In sh.Windows
If TypeName(oWin.document) = "HTMLDocument" Then
Set IE = oWin
Exit For
End If
Next
IE.Visible = True
Application.Wait (Now + TimeValue("00:00:01"))
IE.document.getElementById("idec").Value = "John"
Application.Wait (Now + TimeValue("00:00:01"))
IE.document.getElementById("idee").Value = "Smith"
End Sub
Most of that I've gotten from other posts on this forum, and while I'm a bit of a novice at this, the problem seems to be that for some reason VBA can't find the text boxes with the id of LastName or FirstName. What's more, the IE.Visible = True doesn't bring the IE window back to the foreground, so I'm trying to find the proper line to do that. When I try to run the code, I get an "Object Required" error at:
IE.document.getElementById("idec").Value = "John"
I've tried searching this site and will continue to look, but any help in the meantime would be greatly appreciated!
On the Internet Explorer page, here is the line for the first text box I'm trying to fill:
<input name="componentListPanel:componentListView:1:component:patientLastNameContainer:patientLastName" class="input300" id="idec" type="text" maxlength="60" value="">
Why not automate logging process as well? Login could be stored in Excel and its value read by macro from cell.
As Tim Williams suggests, if there is Iframe on website, use (for me it works only with contentwindow included):
IE.document.getElementById("iFrameIdHere").contentwindow.document.getEleme‌ntById("idec").Value = "John"
Instead of Application.Wait use:
Do Until IE.ReadyState = 4 And IE.Busy = False
DoEvents
Loop
It will save you a lot of time when page loads fast and prevent errors when loading exceeds wait time. Use it ONLY after page reloads (meaning after navigating or anything what causes page reloads, especially .click on HTML elements.
Use early binding, it's a bit faster than creating objects. It can increase performance by a few percent based on page loading speed, the faster pages load, the bigger increase.
Set IE = New InternetExplorer
Finally, you can toggle loading pictures, depending on whether you need to download images from website.
Public Sub ShowPictures(ByVal EnabledStatus As Boolean)
Public ScrapingCancelled as Boolean
Dim obj_Shell
Dim v_Result As Variant
Set obj_Shell = CreateObject("WScript.Shell")
'Reads the registry key that determines whether 'Show pictures' Internet Explorer advanced setting is enabled
v_Result = obj_Shell.RegRead("HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\Display Inline Images")
Select Case v_Result
Case "yes" 'Pictures are displayed
If EnabledStatus = False Then _
obj_Shell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\Display Inline Images", "no", "REG_SZ"
Case "no" 'Pictures are not displayed
If EnabledStatus = True Then _
obj_Shell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\Display Inline Images", "yes", "REG_SZ"
Case Else
ScrapingCancelled = True
End Select
End Sub
No images loaded:
ShowPictures (0)
Images loaded:
ShowPictures (1)
A good practice is to set value to 1 in the end of macro.

How to call a function in Visual Basic

Im fairly new at visual basic and im having trouble using function. ive tried many ways but failed, so ive deleted the funtion to start again. i want this function to run once someone has clicked a button, however the button is on a different form.
When button(btnAdd) is clicked on form 2 i want this to run on form one...
Using writer As System.IO.StreamWriter = New System.IO.StreamWriter(filepath", True)
Dim recipient As String = tbRecipient.Text
If (tbRecipient.Lines.Count > 1) Then
recipient = ""
For Each line As String In tbRecipient.Lines
recipient = recipient & " " & line
Next
recipient = recipient.Trim()
End If
writer.WriteLine(recipient)
End Using
Im not sure if this is the right code to achieve what i want it to do. What the code should do is when the user clicks the button add, it reads the checked options in a checklistbox and adds them to a file. that file is the outputted to a different textbox, which is on a different form. I have the funtion working correctly for the adding of the checkboxlist but need to then display it in a text box on another form. if anyone can help or point me in the right direction that would be great.
Double click on the button(btnAdd) in design window then write:
myFunction()
then in the second form code window:
public function myFunction()
'your code
end function
just call the function name where you want to execute it, or using the reserved keyword Call as Below:
First Way:
'Call by taping the function name
myFunctionName(Argumets)
Second Way:
'Use the Call Keyword:
Call myFunctionName(Argumets)

How to call VBA macro from AHK in Excel when editing a cell?

I have an autohotkey script which calls an Excel macro. Basically I have a universal shortcut to add a task to my custom GTD application in Excel
My AHK code is as follows:
RunMSExcelMacro(MacroName, args) { ; for AHK_L
oExcel := ComObjActive("Excel.Application")
; oExcel.Workbooks("gtd_active.xlsm").Run(MacroName,args)
oExcel.Run("'gtd_active.xlsm'!"+MacroName,args)
;oExcel.Run(MacroName,args)
}
#Space::
InputBox, newTask, Add New Task to GTD, What is the new task?, , 380, 130
if (newtask = "" or ErrorLevel){ ;if blank or "cancel" pressed (ErrorLevel = 1) don't do anything
return
}
else
{RunMSExcelMacro("addFromAHK", newTask)
}
return
The method in Excel is as follows:
'this script allows AutoHotKey to add items to the GTD list
'without having to even access Excel - wtf hax :-)
Sub addFromAHK(ByRef newTask As String)
Dim myCell As Range
'I don't like hardcoding this but I cant be bothered to
'make this reference the constant right now
Set myCell = MasterList.Range("C50000").End(xlUp)
'ugh such a hack. No easy way to get last cell without defiltering
Do Until IsEmpty(myCell) = True
Set myCell = myCell.Offset(1, 0)
Loop
'save the task
myCell.value = newTask
End Sub
Unfortunately, if I am currently editing a cell in Excel I cannot call a macro, so the global shortcut fails. Note this fails before I am able to call the Excel macro.
Is there an easy way to change the AHK code to basically "exit cell editing" if I'm doing that? I don't want to write a huge amount of code to do this but I'm really not sure the best approach here.
The first time I made use of AHK_L's try/catch (yay!). Check out this code example:
RunMyMacro() {
oExcel := ComObjActive("Excel.Application")
try {
oExcel.Run("'MyFile.xlsm'!TestSub")
} catch e {
ControlSend, , {Enter}, ahk_class XLMAIN
Sleep, 200
oExcel.Run("'MyFile.xlsm'!TestSub")
}
}
It's pretty basic, so you'll have to do the fine tuning yourself.
If there's an error calling the macro, we outright assume that that's because we are editing a cell. If you are rather meticulous, you could check the exception's message (e.Message) for an error code. On my machine the message was 0x80010001 Some German BlaBla.
To exit cell editing, we simply send Enter to the Excel Window. If there's multiple Excel Windows, you have to restrict the window title like MyFile.xlsm ahk_class XLMAIN.
After the Sleep (you may want to play around with the exact timeout), we call our macro again.