2010-07-14 4 views
3

J'essaye d'obtenir que ma routine VBA interagisse avec une page qui utilise JavaScript, et qui a déjà réussi dans le passé. Après une mise à jour récente, cela ne fonctionne plus. À ce stade, j'ai besoin soit A) par un bouton de programmation ou B) exécuter la fonction que le bouton appelle. La partie délicate est que le bouton n'a pas de nom déclaré. Il y en a d'autres sur la feuille déclarée dans le code source avec des noms, et je peux très bien interagir avec eux. Voici le code html de la source de la page:Cliquez sur le bouton ou exécutez la fonction JavaScript avec VBA

<input type="button" class="buttonForm" value='Run Report' onclick="exportData(workOrderSearchForm)"/> 

Comme vous pouvez le voir, il ne déclare pas de nom pour le bouton. Dans le passé, ce qui suit a fonctionné:

Set ie = CreateObject("InternetExplorer.application") 
ie.document.all(79).Click 

Avec "79" étant l'indice du numéro d'article. Il semble maintenant que le bouton a été modifié au point « 81 », mais simplement la mise en:

ie.document.all(81).Click 

ne fonctionne pas pour une raison quelconque. Je connais la fonction que je veux exécuter: exportData (workOrderSearchForm), mais je ne sais pas comment le faire en dehors de l'utilisation de la méthode "click".

J'ai recherché une documentation décente concernant l'objet d'application IE, mais je n'arrive pas à trouver une bonne source. Y a-t-il un moyen d'exécuter la fonction?

Répondre

8

Essayez ceci:

Dim CurrentWindow As HTMLWindowProxy: Set CurrentWindow = ie.Document.parentWindow 
Call CurrentWindow.execScript("exportData(workOrderSearchForm)") 

Mais d'abord, vous aurez besoin d'inclure la bibliothèque d'objets Microsoft HTML sous Références (Outils> Références)

0

Comme ceci:

ie.window.exportData(ie.document.forms.workOrderSearchForm) 
+0

Malheureusement il est dit que ce n'est pas une méthode ou une propriété supportée. Il espace également le code en tant que tel "ie.Window.exportData (ie.Document.forms.workOrderSearchForm)" une fois que je l'ai mis. – Michael

+0

Essayez 'ie.window.exportData ie.window.workOrderSearchForm' ou' ie.window.eval "exportData (workOrderSearchForm)" ' – SLaks

+0

Ni l'un ni l'autre ne semble faire l'affaire non plus. Ils produisent la même erreur. – Michael

1

Vous pouvez faire un cycle à travers toutes les balises d'entrée et identifiez la balise pertinente en inspectant l'attribut "le plus identifiant" (id, name, type, innerHTML, ... quel que soit). Voici un Sub() J'utilise dans une feuille Excel qui se connecte automatiquement à un site Web

Sub FormAction(Doc As MSHTML.HTMLDocument, ByVal Tag As String, ByVal Attrib As String, ByVal Match As String, ByVal Action As String) 
Dim ECol As MSHTML.IHTMLElementCollection 
Dim IFld As MSHTML.IHTMLElement 
Dim Tmp As String 

    Set ECol = Doc.getElementsByTagName(Tag) 
    For Each IFld In ECol           ' cycle thru all <[tag]> elements 
     If VarType(IFld.getAttribute(Attrib)) <> vbNull Then  ' does it contain the attribute 
      If Left(IFld.getAttribute(Attrib), Len(Match)) = Match Then 
       If Action = "/C/" Then 
        IFld.Click 
       Else 
        IFld.setAttribute "value", Action 
       End If 
       Exit Sub 
      End If 
     End If 
    Next 
End Sub 

La fonction prend les paramètres suivants:

  • Doc .... l'objet DOM HTML
  • Balise .... la balise sur laquelle vous voulez travailler (généralement entrée, image, a, ...)
  • Attrib .... l'attribut dont vous voulez faire correspondre la valeur
  • Match .... l'appariement valeur pour l'attribut
  • action ..... si «/C/» le .Cliquez() action est effectuée sur la balise qui correspond, sinon la valeur d'action est mis en valeur l'attribut de la balise

Si vous voulez pour accrocher tout attribut contenant du code JavaScript (comme « onclick ») ne faut pas oublier que le code que vous voyez dans la source HTML est embeded dans une fonction anonyme, comme

function anonymous() 
{ 
onclick="exportData(workOrderSearchForm)"; 
} 

vous devez considérer cela en utilisant un Fonction Instr() ou similaire, si vous voulez accrocher par exemple "exportData (workOrder".

Également très important: donnez suffisamment de temps à la page pour naviguer vers et pour l'objet DOM à charger. Je remarque dans mon entreprise qu'une fois les pages modifiées, les temps de chargement augmentent parfois considérablement.

Je réussiras par ceci:

Sub MyMainSub() 
Dim Browser As SHDocVw.InternetExplorer 
Dim HTMLDoc As MSHTML.HTMLDocument 
' my other Dim's 

    ' start browser 
    Set Browser = New SHDocVw.InternetExplorer 
    Browser.navigate "http://www.whatever.com" 
    WaitForBrowser Browser, 5   ' wait for browser, but not more than 5 sec 

    ' gain control over DOM object 
    Set HTMLDoc = Browser.document 
    WaitForBrowser Browser, 5   ' wait for browser, but not more than 5 sec 

    ' do actions 
    ' FormAction HTMLDoc, w, x, y, z 

End Sub 


Sub WaitForBrowser(Browser As SHDocVw.InternetExplorer, Optional TimeOut As Single = 10) 
Dim MyTime As Single 

    MyTime = Timer     ' seconds since midnight 
    Do While Browser.Busy Or (Timer <= MyTime + TimeOut) 
     DoEvents      ' go do something else 
    Loop 

    If Browser.Busy Then 
     MsgBox "I waited for " & Timer - MyTime & " seconds, but browser still busy" & vbCrLf & _ 
       "exititing Login sequence now" 
     End 
    End If 
End Sub 

Espérons que cela est assez inspirant pour vous de créer votre solution.

Bonne chance MikeD

Questions connexes