"method 'add' of object 'SmartArtNodes' failed" - excel

I have the follow code that is running in an Excel and it's calling a PowerPoint slide. I am setting a text to each existing node of the SmartArt and it's working. However, I am getting error when I use AddNode method (oSmartArt.AllNodes.Add.AddNode). What am I doing wrong?
Set oSmartArt = d_ppt_output.Slides(SLIDE_SMART).Shapes("MyList").SmartArt
x = 1
While Cells(x, 1).Text <> ""
If x > oSmartArt.Nodes.Count Then
oSmartArt.AllNodes.Add.AddNode ''''' ERROR IS HERE!
End If
oSmartArt.AllNodes(x).Shapes.TextFrame2.TextRange.Text = ActiveSheet.Cells(x, 2).Text
x = x + 1
Wend
I also replaced oSmartArt.AllNodes.Add.AddNode by oSmartArt.Nodes.Add.AddNode but I get the same problem.
The error is:
-2147467259 (80004005)
Method 'add' of object 'SmartArtNodes' failed
The whole code can by found here - https://drive.google.com/drive/folders/1_O79iiG7hbBjMHMSH6kZGkWmjN1WGorR?usp=sharing

As posted, your code doesn't run. You can't reference a slide with a name that's not in quotes. I created a super-simple version in PowerPoint that starts with a 5-member SmartArt. This is running without an error. It adds a new node and fills in the text as expected:
Sub Test()
Set oSmartArt = ActivePresentation.Slides(1).Shapes(2).SmartArt
oSmartArt.AllNodes.Add.AddNode
oSmartArt.AllNodes(6).Shapes.TextFrame2.TextRange.Text = "Wha?"
End Sub

Related

Excel VBA Find Duplicates and post to different sheet

I keep having an issue with some code in VBA Excel was looking for some help!
I am trying to sort through a list of names with corresponding phone numbers, checking for multiple names under the same phone number. Then post those names to a separate sheet.
So far my code is:
Sub main()
Dim cName As New Collection
For Each celli In Columns(3).Cells
Sheets(2).Activate
On Error GoTo raa
If Not celli.Value = Empty Then
cName.Add Item:=celli.Row, Key:="" & celli.Value
End If
Next celli
On Error Resume Next
raa:
Sheets(3).Activate
Range("a1").Offset(celli.Row - 1, 0).Value = Range("a1").Offset(cName(celli.Value) - 1, 0).Value
Resume Next
End Sub
When I try to run the code it crashes Excel, and does not give any error codes.
Some things I've tried to fix the issue:
Shorted List of Items
Converted phone numbers to string using cstr()
Adjusted Range and offsets
I'm pretty new to all this, I only managed to get this far on the code with help from other posts on this site. Not sure where to go with this since it just crashes and gives me no error to look into. Any ideas are appreciated Thank you!
Updated:
Option Explicit
Dim output As Worksheet
Dim data As Worksheet
Dim hold As Object
Dim celli
Dim nextRow
Sub main()
Set output = Worksheets("phoneFlags")
Set data = Worksheets("filteredData")
Set hold = CreateObject("Scripting.Dictionary")
For Each celli In data.Columns(3).Cells
On Error GoTo raa
If Not IsEmpty(celli.Value) Then
hold.Add Item:=celli.Row, Key:="" & celli.Value
End If
Next celli
On Error Resume Next
raa:
nextRow = output.Range("A" & Rows.Count).End(xlUp).Row + 1
output.Range("A" & nextRow).Value = data.Range("A1").Offset(hold(celli.Value) - 1, 0).Value
'data.Range("B1").Offset(celli.Row - 1, 0).Value = Range("B1").Offset(hold
Resume Next
End Sub
Update2:
Used hold.Exists along with an ElseIf to remove the GoTo's. Also changed it to copy and paste the row to the next sheet.
Sub main()
Set output = Worksheets("phoneFlags")
Set data = Worksheets("filteredData")
Set hold = CreateObject("Scripting.Dictionary")
For Each celli In data.Columns(2).Cells
If Not hold.Exists(CStr(celli.Value)) Then
If Not IsEmpty(celli.Value) Then
hold.Add Item:=celli.Row, Key:="" & celli.Value
Else
End If
ElseIf hold.Exists(CStr(celli.Value)) Then
data.Rows(celli.Row).Copy (Sheets("phoneFlags").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0))
'output.Range("A" & nextRow).Value = data.Range("A1").Offset(hold(celli.Value) - 1, 0).Value
End If
Next celli
End Sub
When developing code, don't try (or be afraid of) errors as they are pointers to help fix the code or the logic. As such, don't use On Error unless it is absolutely indicated in the coding algorithm (*). using On Error when not necessary only hides errors, does not fix them and when coding it is always better to avoid the errors in the first place (good logic).
When adding to the Dictionary, first check to see if the item already exists. The Microsoft documentation notes that trying to add an element that already exists causes an error. An advantage that the Dictionary object has over an ordinary Collection object in VBA is the .exists(value) method, which returns a Boolean.
The short answer to your question, now that I have the context out of the way, is that you can first check (if Not hold.exists(CStr(celli.Value)) Then) and then add if it does not already exist.
(*) As a side note, I was solving an Excel macro issue yesterday which took me most of the day to nut out, but the raising of errors and the use of debugging code helped me make some stable code rather than some buggy but kind-of-working code (which is what I was fixing in the first place). However, the use of error handling can be a short cut in some instances such as:
Function RangeExists(WS as Worksheet, NamedRange as String) As Boolean
Dim tResult as Boolean
Dim tRange as Range
tResult = False ' The default for declaring a Boolean is False, but I like to be explicit
On Error Goto SetResult ' the use of error means not using a loop through all the named ranges in the WS and can be quicker.
Set tRange = WS.Range(NamedRange) ' will error out if the named range does not exist
tResult = True
On Error Goto 0 ' Always good to explicitly limit where error hiding occurs, but not necessary in this example
SetResult:
RangeExists = tResult
End Function

VBA-Object Required Error

I was writing a function with ws declared already. It works well under the private sub of the command button but when i extract it as a function it shows the object required error. The file is too large and I must make it as a function and call it but the error stopped my program running.
Could anyone please help me thanks a lot.
If Month(ws.Cells(j, 11)) = "a" And Year(ws.Cells(j, 11)) = ComboBox1.Text Then 'this sentence error
If ws.Cells(j, 5) <> "-" Then 'this sentence also error if I deleted the above one
n = 2
Else: n = 1
End If
p = 1

Getting list of elements from web listbox

I'm trying to count all elements in a listbox on a webpage (eventually loop through them, but solving this issue will help with looping):
Im quite new to VBA, but i do believe this is a listbox object, as in firebug name of this object has "listbox" at the end.
All the suggestions i found here or elsewhere related to either .ListCount or .ListIndex
Somehow, either of these result in error 438, object not supported.
Piece of code below.
Can you suggest please?
With IE.document
.getElementById("xxx_startDay").Value = "1"
.getElementById("xxx_startMonth").Value = "JAN"
.getElementById("xxx_startYear").Value = "2017"
.getElementById("xxx_endDay").Value = "31"
.getElementById("xxx_endMonth").Value = "JAN"
.getElementById("xxx_endYear").Value = "2017"
'IE.document.getElementById("xxx_accountItemsListBox").Focus
Set listMPAN = IE.document.getElementById("xxx_accountItemsListBox")
listMPAN.selectedIndex = 5
MsgBox (listMPAN.ListCount)
End With
Help was closer than i thought.
Turned out the ListBox was not the real listbox, it was some other html element with listbox generated on the server side (just trying to repeat what i was told):
<select size="4" name="xyz" multiple="multiple" id="xxx_accountItemsListBox" class="accountItemsListBox">
so the .ListCount wasnt recognised. Instead i had to use .Length and
msgbox(listMPAN.Length)
worked perfectly. Now looping through it should be simple.
Thank you.
This was my alternative answer:
On Error GoTo endCount
For i = 0 To 100
Debug.Print myDoc2.getElementById("quoteDropdown").Item(i).Value
Next i
endCount:
On Error GoTo 0
If i <> 0 Then
Debug.Print "there are " & i & " options."
End If

VBA Excel - Mantaining Public Variables With Button Press

I'm trying to Create a document that has a bunch o constant strings.
I've declared then Public in a Module like this:
Public Abc As String
In "ThisWorkbook" I run the following code to initialize de variable
Private Sub Workbook_Open()
Abc = "C5"
End Sub
I have Buttons coded to change some values like:
If Range(Abc) = "" Then
Range(Abc) = 1
Else
Range(Abc) = Range(Abc) + 1
End If
When I run a button with this code:
Sub BotaoNovoDia()
i = 3
While i <= 33
If Cells(i, 11) = "" Then
Cells(i, 11) = Range(Apresentacao)
Cells(i, 12) = Range(Aceitacao)
Cells(i, 13) = Range(Aceitou)
Cells(i, 31) = Range("D41")
Cells(i, 11).Interior.Color = Range(Apresentacao).Interior.Color
Cells(i, 12).Interior.Color = Range(Aceitacao).Interior.Color
If Range("K34") < 0.65 Then
Range("K34").Interior.Color = vbRed
Else
Range("K34").Interior.Color = vbGreen
End If
If Range("L34") < 0.45 Then
Range("L34").Interior.Color = vbRed
Else
Range("L34").Interior.Color = vbGreen
End If
Range(Aceitou) = 0
Range(Rejeitou) = 0
Range(NaoApres) = 0
End
Else
i = i + 1
End If
Wend
End Sub
And i try to run the first button again I get and error saying: "Run-Time error '1004': Method 'Range' of object '_Global' failed"
the debug button takes me to the fisrt line that tries to access to the public variables value. What can i do to mantain the values in the Public variables?
When you call End (By itself, not as part of End If, etc) you clear your Globals.
Don't use End.
Using a named range is a great idea; but there's no reason why your public declaration shouldn't work - except for that pesky End statement. (I missed that first read through...)
However, your scope isn't clear in each of your functions, e.g. which worksheet is the Range referring to, so if one function works on another worksheet, pushing the button that fires "Change" could refer to a different place that doesn't like that reference.
e.g. your ranges should be something like SomeWorkbook.TheWorksheet.Range(<range>) and when you're changing the cell value, you should use .Value to ensure there's no ambiguity - you'll know from searching through here that error 1004 is the least descriptive error code...

Excel VBA object sub call with 2 object parameters gives compile error: expected =

I am calling an object's subroutine in Microsoft excel vba. The sub has 2 parameters, both objects themselves. The line of code I typed is giving an error-> Compile Error: Expected =
Here is the section of code that it occurs in:
' Copy the info from the old sheet and paste into the new sheet
Dim employee as CEmployee
For i = 2 To eswbMaxRow
Set employee = New CEmployee
employee.setNames (eswb.Worksheets("Employee Info").Cells(i, wbColumns.infoNameCol).value)
employee.loadFromAnotherWorkbook(eswb,wbcolumns) ' <- This line is giving the compile error
Next I
I don't understand why this is. This code is similar to code I already have that works fine.
This code works perfectly (Note: this is a separate function):
With ThisWorkbook.Worksheets(sheet)
Do While (.Cells(i, 1).value <> Empty)
' Create an object and set the name property
Set employee = New CEmployee
employee.setNames (.Cells(i, 1).value)
employee.loadFromScratch ' <- This sub is nearly identical to the one that is causing the problem. The only difference is it doesn't take object parameters
i = i + 1
Loop
End With
This is how I am declaring the subroutine that I am calling that gives the compile error:
Public Sub loadFromAnotherWorkbook(ByVal wb As Workbook, ByVal wbColumns As CColumns)
The objects I pass into this sub are of the correct type.
This isn't a function, so I don't understand why I would need to use an equal sign. Anyone know what I am doing wrong?
When calling a Sub, you don't enclose the parameters in brackets
Use it like this
employee.loadFromAnotherWorkbook eswb, wbcolumns

Resources