I had a excel report that extracts data from Avaya CMS, however they moved the Avaya CMS application from my workstation to a RD Web Access. Now the VBA is not working anymore since the old CMS that was installed on my workstation is now in a RD web access. Is it possible to access Avaya CMS on a RD web access to extract a report to excel thru VBA?
Thanks in advance!!
Sub GetIntervalData()
Dim cvsApp As Object
Dim cvsConn As Object
Dim cvsSrv As Object
Dim Rep As Object
Dim Info As Object, Log As Object, b As Object
Set cvsApp = CreateObject("ACSUP.cvsApplication")
'Set cvsConn = CreateObject("ACSCN.cvsConnection")
Set cvsSrv = CreateObject("ACSUPSRV.cvsserver")
Set Rep = CreateObject("ACSREP.cvsReport")
'Clear Data
Sheets("Domestic Interval Data").Select
Range("A1:AR300").ClearContents
Sheets("Domestic").Activate
serverAddress = Range("B1").Value
UserName = Range("B2").Value
Password1 = Range("C2").Value
If cvsApp.CreateServer(UserName, "", "", serverAddress, False, "ENU", cvsSrv, cvsConn) Then
If cvsConn.Login(UserName, Password1, serverAddress, "ENU") Then
On Error Resume Next
cvsSrv.Reports.ACD = 1
Set Info = cvsSrv.Reports.Reports("Historical\Designer\APS Report (MultiSkill)")
If Info Is Nothing Then
If cvsSrv.Interactive Then
MsgBox "The report Historical\Designer\APS Report (MultiSkill) was not found on ACD 1.", vbCritical Or vbOKOnly, "Avaya CMS Supervisor"
Else
Set Log = CreateObject("ACSERR.cvsLog")
Log.AutoLogWrite "The report Historical\Designer\APS Report (MultiSkill) was not found on ACD 1."
Set Log = Nothing
End If
Else
b = cvsSrv.Reports.CreateReport(Info, Rep)
If b Then
Rep.Window.Top = 75
Rep.Window.Left = 690
Rep.Window.Width = 19140
Rep.Window.Height = 11400
Rep.TimeZone = "default"
Rep.SetProperty "Split/Skills","1555;1551;1552;1553;1554;1570;1998;1999"
Rep.SetProperty "Dates", "2/14/2018"
Rep.SetProperty "Times", "00:00-23:30"
b = Rep.ExportData("", 9, 0, False, False, True)
Rep.Quit
If Not cvsSrv.Interactive Then cvsSrv.ActiveTasks.Remove Rep.TaskID
Set Rep = Nothing
End If
End If
Set Info = Nothing
End If
cvsApp.Servers.Remove cvsSrv.ServerKey
cvsConn.Logout
cvsConn.Disconnect
cvsSrv.Connected = False
Set Log = Nothing
Set Rep = Nothing
Set cvsSrv = Nothing
Set cvsConn = Nothing
Set cvsApp = Nothing
Sheets("Domestic Interval Data").Select
Range("A1").Select
ActiveSheet.Paste
End If
Sheets("Domestic").Activate
End Sub
**This code creates a avaya cms session and runs a report, extracts it and pastes directly to excel
It has been over seven years since I used Avaya CMS but I use to design reports out of the CMS Supervisor. Do you have access to this? If so you should be able to write a simple report that will extract the data you need. I will see if I can find my old how to guide.
Related
I am getting the following error while running below macro. I have copy this macro from this side only. I am using below macro to copy dump in excel from Avaya CMS.
Code is as below. I am getting error on step:
Set cvsApp = CreateObject("ACSUP.cvsApplication")
Sub GetIntervalData()
Dim cvsApp As Object
Dim cvsConn As Object
Dim cvsSrv As Object
Dim Rep As Object
Dim Info As Object, Log As Object, b As Object
On Error Resume Next
Set cvsApp = CreateObject("ACSUP.cvsApplication")
Set cvsConn = CreateObject("ACSCN.cvsConnection")
Set cvsSrv = CreateObject("ACSUPSRV.cvsserver")
Set Rep = CreateObject("ACSREP.cvsReport")
'Clear Data
Sheets("Sheet1").Select
Range("A1:AR300").ClearContents
Sheets("Domestic").Activate
serverAddress = "*****"
UserName = "*****"
Password1 = "*****"
If cvsApp.CreateServer(UserName, "", "", serverAddress, False, "ENU", cvsSrv, cvsConn) Then
If cvsConn.Login(UserName, Password1, serverAddress, "ENU") Then
On Error Resume Next
cvsSrv.Reports.ACD = 1
Set Info = cvsSrv.Reports.Reports("Historical\Designer\SLA for skill(s) Daily Summary")
If Info Is Nothing Then
If cvsSrv.Interactive Then
MsgBox "The report Historical\Designer\SLA for skill(s) Daily Summary", vbCritical Or vbOKOnly, "Avaya CMS Supervisor"
Else
Set Log = CreateObject("ACSERR.cvsLog")
Log.AutoLogWrite "The report Historical\Designer\SLA for skill(s) Daily Summary"
Set Log = Nothing
End If
Else
b = cvsSrv.Reports.CreateReport(Info, Rep)
If b Then
Rep.Window.Top = 75
Rep.Window.Left = 690
Rep.Window.Width = 19140
Rep.Window.Height = 11400
Rep.TimeZone = "default"
Rep.SetProperty "Split/Skills", "CA10 CRU Parts;CA10 CRU Tech;CA14 ICG;CA10 LCSC;CA10 USEO P_1;CA14 ICG Overflow"
Rep.SetProperty "Dates", "8/1/2020"
Rep.SetProperty "Times", "00:00-23:30"
b = Rep.ExportData("", 9, 0, False, False, True)
Rep.Quit
If Not cvsSrv.Interactive Then cvsSrv.ActiveTasks.Remove Rep.TaskID
Set Rep = Nothing
End If
End If
Set Info = Nothing
End If
cvsApp.Servers.Remove cvsSrv.ServerKey
cvsConn.logout
cvsConn.Disconnect
cvsSrv.Connected = False
Set Log = Nothing
Set Rep = Nothing
Set cvsSrv = Nothing
Set cvsConn = Nothing
Set cvsApp = Nothing
Sheets("Sheet1").Select
Range("A1").Select
ActiveSheet.Paste
End If
Sheets("Sheet1").Activate
End Sub
enter image description here
enter image description hereCan you give us a screen shot of your VBA References? (if there are MISSING:Libs, that are checked, they should be un-checked) Can you also look in the object browser in Excel to see if that object is actually available?
You shouldn't have to use CreateObject() late binding if the object/lib is referenced. Tools -> References in VBA editor.
I've written a script in vba to get some set names from a webpage and the script is getting them accordingly until it catches an error somewhere within the execution. This is the first time I encountered such error.
What my script is doing is get all the links under Company Sets and then tracking down each of the links it goes one layer deep and then following all the links under Set Name it goes another layer deep and finally parse the table from there. I parsed the name of PUBLISHED SET which is stored within the variable bName instead of the table as the script is getting bigger. I used IE to get the PUBLISHED SET as there are few leads which were causing encoding issues.
I searched through all the places to find any workaround but no luck.
However, I came across this thread where there is a proposed solution written in vb but can't figure out how can I make it work within vba.
Script I'm trying with:
Sub FetchRecords()
Const baseUrl$ = "https://www.psacard.com"
Const link = "https://www.psacard.com/psasetregistry/baseball/company-sets/16"
Dim IE As New InternetExplorer, Htmldoc As HTMLDocument
Dim Http As New XMLHTTP60, Html As New HTMLDocument, bName$, tRow As Object
Dim post As Object, elem As Object, posts As Object, I&, R&, C&
Dim key As Variant
Dim idic As Object: Set idic = CreateObject("Scripting.Dictionary")
With Http
.Open "GET", link, False
.send
Html.body.innerHTML = .responseText
End With
Set posts = Html.querySelectorAll(".dataTable tr td a[href*='/psasetregistry/baseball/company-sets/']")
For I = 0 To posts.Length - 7
idic(baseUrl & Split(posts(I).getAttribute("href"), "about:")(1)) = 1
Next I
For Each key In idic.Keys
With Http
.Open "GET", key, False
.send
Html.body.innerHTML = .responseText
End With
For Each post In Html.getElementsByTagName("a")
If InStr(post.getAttribute("title"), "Contact User") > 0 Then
If InStr(post.ParentNode.getElementsByTagName("a")(0).getAttribute("href"), "publishedset") > 0 Then
IE.Visible = True
IE.navigate baseUrl & Split(post.ParentNode.getElementsByTagName("a")(0).getAttribute("href"), "about:")(1)
While IE.Busy = True Or IE.readyState < 4: DoEvents: Wend
Set Htmldoc = IE.document
bName = Htmldoc.querySelector("h1 b.text-primary").innerText
If InStr(bName, "/") > 0 Then bName = Split(Htmldoc.querySelector(".inline-block a[href*='/contactuser/']").innerText, " ")(1)
R = R + 1: Cells(R, 1) = bName
End If
End If
Next post
Next key
IE.Quit
End Sub
I get that error pointing at the following line after extracting records between 70 to 90:
bName = Htmldoc.querySelector("h1 b.text-primary").innerText
The error looks like:
Automation Error: old format or invalid type library
Proposed solution in the linked thread written in vb (can't convert to vba):
'save the current settings for easier restoration later
Dim oldCI As System.Globalization.CultureInfo = _
System.Threading.Thread.CurrentThread.CurrentCulture
'change the settings
System.Threading.Thread.CurrentThread.CurrentCulture = _
New System.Globalization.CultureInfo("en-US")
Your code here
'restore the previous settings
System.Threading.Thread.CurrentThread.CurrentCulture = oldCI
I'm brand spanking new to VBA. But I've programmed a bit in SAS, just a bit in Assembler (mainframe and PC), Word Perfect (macros), a bit in Java, HTML, other stuff. What I do is, when I have a problem and I think I can program it, I look for code on the internet and adjust it to fit my needs. I have read a little bit of VBA programming. What I'm trying to do is make a macro to save a bunch of Outlook e-mail messages with PDFMAKER. I've come up with the below, so far. When I step the program, pmkr2 gets assigned type "ObjectPDFMaker" and stng gets assigned type "ISettings". So far, so good. Then I try to set stng and can't do it. I get the error "Method or data member not found." If I get rid of Set it highlights .ISettings and I get the same error. I go into F2 and the AdobePDFMakerforOffice library is there, and the class ISettings is there, but I can't seem to set stng. I'm wa-a-a-ay frustrated. Please help.
Sub ConvertToPDFWithLinks()
Dim pmkr2 As Object
Set pmkr2 = Application.COMAddIns.Item(6).Object ' Assign object reference.
Dim pdfname As String
pdfname = "C:\stuff\stuff\tester.pdf"
Dim stng As AdobePDFMakerForOffice.ISettings
Set stng = AdobePDFMakerForOffice.ISettings
stng.AddBookmarks = True
stng.AddLinks = True
stng.AddTags = True
stng.ConvertAllPages = True
stng.CreateFootnoteLinks = True
stng.CreateXrefLinks = True
stng.OutputPDFFileName = pdfname
stng.PromptForPDFFilename = False
stng.ShouldShowProgressDialog = True
stng.ViewPDFFile = False
pmkr.GetCurrentConversionSettings stng
pmkr2.CreatePDFEx stng, 0
Set pmkr2 = Nothing ' Discontinue association.
End Sub
I updated your code a little. See if this has any affect:
Sub ConvertToPDFWithLinks()
Dim pmkr2 As AdobePDFMakerForOffice.PDFMaker
'Set pmkr2 = Application.COMAddIns.Item(6).Object ' Assign object reference.
Set pmkr2 = Nothing
For Each a In Application.COMAddIns
If InStr(UCase(a.Description), "PDFMAKER") > 0 Then
Set pmkr2 = a.Object
Exit For
End If
Next
If pmkr2 Is Nothing Then
MsgBox "Cannot Find PDFMaker add-in", vbOKOnly, ""
Exit Sub
End If
Dim pdfname As String
pdfname = "C:\stuff\stuff\tester.pdf"
Dim stng As AdobePDFMakerForOffice.ISettings
pmkr2.GetCurrentConversionSettings stng
stng.AddBookmarks = True
stng.AddLinks = True
stng.AddTags = True
stng.ConvertAllPages = True
stng.CreateFootnoteLinks = True
stng.CreateXrefLinks = True
stng.OutputPDFFileName = pdfname
stng.PromptForPDFFilename = False
stng.ShouldShowProgressDialog = True
stng.ViewPDFFile = False
pmkr2.CreatePDFEx stng, 0
Set pmkr2 = Nothing ' Discontinue association.
End Sub
The main changes were in how the addin is obtained and in how stng is created.
I have a code that works for me about 70% of the time, the other times it throws the Error code 91 "Object Variable or With block Variable not set". If i click End and re-run it it will work fine.
The function is taking data that is entered into cells of an excel spreadsheet and populating text boxes, checking radio buttons, and selecting from drop-down lists on a webpage.
I can't post a link to the actual webpage for privacy issues but I'm hoping someone can help me why the error is coming up?
The line that shows the error is
drp.selectedIndex = Thisworkbook.sheets("sheet1").Range("L2").
Sub FillInternetForm()
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
'set references for copying to submitted reps sheet and deleting for next rep
Application.ScreenUpdating = False
'create new instance of IE.
ie.navigate "removed for privacy"
'go to web page listed inside quotes
ie.Visible = True
While ie.busy
DoEvents 'wait until IE is done loading page.
Wend
'select onboarding system CRIS or ENS
Set html = ie.document
Dim drp As HTMLFormElement
Set drp = html.getElementById("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff45_1$ctl00 $DropDownChoice")
drp.selectedIndex = ThisWorkbook.Sheets("sheet1").Range("L2")
'set address nickname based on value
Set drp = html.getElementById("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff32_1$ctl00 $Lookup")
drp.selectedIndex = ThisWorkbook.Sheets("sheet1").Range("m2")
'set market based on value
Set drp = html.getElementById("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff6_1$ctl00$ DropDownChoice")
drp.selectedIndex = ThisWorkbook.Sheets("sheet1").Range("e2")
'check Not moved from another partner
ie.document.getElementById("ctl00_m_g_62853594_bb4b_4cec_8b5c_17fb6abb735e_ff46_1_ctl00_ctl01").Click
'input name and ssn based on excel sheet values
ie.document.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff3_1$ctl00$ctl00$TextField").Value = ThisWorkbook.Sheets("sheet1").Range("a2")
ie.document.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff4_1$ctl00$ctl00$TextField").Value = ThisWorkbook.Sheets("sheet1").Range("b2")
ie.document.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff5_1$ctl00$ctl00$TextField").Value = ThisWorkbook.Sheets("sheet1").Range("c2")
'input extra fields based on ICL value
'owner
ie.document.all("ctl00_m_g_62853594_bb4b_4cec_8b5c_17fb6abb735e_ff11_1_ctl00_ctl00_TextField").Value = ThisWorkbook.Sheets("sheet1").Range("j2")
'city
ie.document.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff14_1$ctl00$ctl00$TextField").Value = ThisWorkbook.Sheets("sheet1").Range("f2")
'state
ie.document.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff15_1$ctl00$ctl00$TextField").Value = ThisWorkbook.Sheets("sheet1").Range("g2")
'address
ie.document.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff13_1$ctl00$ctl00$TextField").Value = ThisWorkbook.Sheets("sheet1").Range("i2")
'phone
ie.document.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff10_1$ctl00$ctl00$TextField").Value = ThisWorkbook.Sheets("sheet1").Range("k2")
'zip
ie.document.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff16_1$ctl00$ctl00$TextField").Value = ThisWorkbook.Sheets("sheet1").Range("h2")
End Sub
While ie.busy is probably to blame. Use Loop Until ie.readyState = READYSTATE_COMPLETE instead.
I would cast .Range("L2") as an integer using CInt(.Range("L2")). You have a reference to the HTML Object library set. You should go ahead and add a reference to Microsoft Internet Controls. This way you'll get advantages of intellisense and internet constants. If you don't want to set the reference add Const READYSTATE_COMPLETE = 4 to the code and change the ie references back
Sub FillInternetForm()
Dim ie As InternetExplorer
Dim doc As HTMLDocument
Set ie = New InternetExplorer
'set references for copying to submitted reps sheet and deleting for next rep
Application.ScreenUpdating = False
'create new instance of IE.
ie.navigate "removed for privacy"
'go to web page listed inside quotes
ie.Visible = True
Do
DoEvents
Loop Until ie.readyState = READYSTATE_COMPLETE
With Sheets("sheet1")
'select onboarding system CRIS or ENS
Set doc = ie.document
Dim drp As HTMLFormElement
Set drp = HTML.getElementById("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff45_1$ctl00 $DropDownChoice")
drp.selectedIndex = CInt(.Range("L2"))
'set address nickname based on value
Set drp = HTML.getElementById("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff32_1$ctl00 $Lookup")
drp.selectedIndex = CInt(.Range("m2"))
'set market based on value
Set drp = HTML.getElementById("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff6_1$ctl00$ DropDownChoice")
drp.selectedIndex = CInt(.Range("e2"))
'check Not moved from another partner
doc.getElementById("ctl00_m_g_62853594_bb4b_4cec_8b5c_17fb6abb735e_ff46_1_ctl00_ctl01").Click
'input name and ssn based on excel sheet values
doc.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff3_1$ctl00$ctl00$TextField").value = .Range("a2")
doc.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff4_1$ctl00$ctl00$TextField").value = .Range("b2")
doc.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff5_1$ctl00$ctl00$TextField").value = .Range("c2")
'input extra fields based on ICL value
'owner
doc.all("ctl00_m_g_62853594_bb4b_4cec_8b5c_17fb6abb735e_ff11_1_ctl00_ctl00_TextField").value = .Range("j2")
'city
doc.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff14_1$ctl00$ctl00$TextField").value = .Range("f2")
'state
doc.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff15_1$ctl00$ctl00$TextField").value = .Range("g2")
'address
doc.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff13_1$ctl00$ctl00$TextField").value = .Range("i2")
'phone
doc.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff10_1$ctl00$ctl00$TextField").value = .Range("k2")
'zip
doc.all("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff16_1$ctl00$ctl00$TextField").value = .Range("h2")
End With
End Sub
I agree with #Thomas Inzina in that it's probably because the document hasn't fully loaded yet.
But I've found with my past projects that the best way to handle these 30% failure rates is to just "wait a bit longer" before processing or referring to elements.
Try adding a DoEvents and a Sleep command before you selectedIndex call.
See if it makes a difference
At the top of your module (before any subs are declared)
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Then add the two lines before you start set the doc variable
Doevents
Sleep 2000 ' Sleep two seconds (2000 ms)
Set doc = ie.document
You can play with the sleep value once you get a number that works for you
EDIT - added solution
A more reliable way is to actually run a loop that has DoEvents/Sleep and an incrementing counter for numTries. It exits the loop only when the check for getElementById doesn't fail - or your maxTries counter is reached.
Pretty simple loop but let me know if you need an example
EDIT - EXAMPLE: A wait until loaded loop
Change this
Set drp = HTML.getElementById("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff45_1$ctl00 $DropDownChoice")
drp.selectedIndex = CInt(.Range("L2"))
To this:
Dim iTries As Integer
Dim iMaxTries As Integer ' it's better to turn this into a const at top of your sub
iMaxTries = 3
iTries = 0
While (iTries < iMaxTries) And IsNull(HTML.getElementById("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff45_1$ctl00 $DropDownChoice"))
iTries = iTries + 1
DoEvents
Sleep 750 ' try 3/4 second delays to start with
Wend
If iTries = iMaxTries Then
MsgBox "Did not load HTML element in " & iMaxTries & " tries"
Exit Sub
End If
' Should all be loaded and ready to process now
Set drp = HTML.getElementById("ctl00$m$g_62853594_bb4b_4cec_8b5c_17fb6abb735e$ff45_1$ctl00 $DropDownChoice")
drp.selectedIndex = CInt(.Range("L2"))
I created an excel1 which has a login function (I've the username and password):
Pic: showing login window. (but I can't post the pic here because I don't have 10 reputation...)
Now I have another excel2 which need to read some information from excel1, and I want this can be done by just click a button, so I use vb.
But how to sent username&password to excel1 and open excel1 in background(I don't want the open process showing on screen).
Thanks
Add more description of my "login" window:
I insert an VBA Userform as the login window, it includes:
1, username_box: user can input login name here
2, pw_box: user can input password here
3, login_button: if click this button, sub login_button_Click() will be triggered
4, quit_button: if click this button, login will be cancelled
Private Sub login_button_Click()
Dim login_flag As Boolean
login_flag = False
'there is a sheet "users" which recorded the username and its password
For r = 2 To 100 Step 1
If username_box.Text = Sheets("users").Cells(r, 1).Value And pw_box.Text = Sheets("users").Cells(r, 2).Value Then
login_flag = True
Application.Visible = True
login_window.Hide
pw_box = ""
End If
Next r
If login_flag = False Then
MsgBox "Input wrong"
pw_box = ""
End If
End Sub
a lot depends on how the login to excel1.
If you use Workbook_Open Event to call UserForm where user fills login details, you can disable them Application.EnableEvents = False, example:
Sub OpenWb()
Dim FilePath As String
Dim WbSource As Workbook
Dim WbDest As Workbook
Dim ActWindow As String
Set WbDest = ActiveWorkbook
Application.EnableEvents = False
FilePath = "C:\tmp\excel1.xlsm" 'excel with password
Set WbSource = Workbooks.Open(FilePath)
ActWindow = ActiveWorkbook.Name
ActiveWindow.Visible = False
WbDest.Sheets(1).Cells(1, 1) = WbSource.Sheets(2).Cells(2, 2)
Application.EnableEvents = True
Windows(ActWindow).Visible = True
WbSource.Close savechanges:=False
End Sub
If you want read some information so that user dont see you can set the visibility to false:
ActiveWindow.Visible = False
From what i understand your problem might be.
When you open a excel workbook as intance, the userform wont show up. If it is data transfer you talking about, then you can easily do it without triggering the workbook.open module.