Retrieve only checkboxes that have been checked vba - excel

Hello I have this loop that checks weather checkboxes have been checked or not, but the array that this loop creates stores every single checkbox value of the list of checkboxes regardless if it is checked or not. So, I am not sure how to create a second loop that will gather only the checkboxes that have been checked out of the array SelectedItemArray1(i). Thank you very much for your help in advance and this is what I have so far.
For i = 0 To Sheet1.ListBox1.ListCount - 1
If Sheet1.ListBox1.Selected(i) = True Then
SelectedItemArray1(i) = Sheet1.ListBox1.List(i)
End If
MsgBox SelectedItemArray1(i)
Next

Try this (untested) code and see how well it works for you:
Dim Msg As String
Dim i As Integer
If ListBox1.ListIndex = -1 Then
Msg = "Nothing"
Else
Msg = ""
For i = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(i) Then
Msg = Msg & ListBox1.List(i) & vbCrLf
End If
Next i
End If
If your list box allows multi-selection of check boxes, then it's a different kind of animal. I did some googling and found this article, which should hopefully give you some ideas. Also, take a look at this article, which seems more complete.
EDIT:
I thought it might help to give the multi-select code too, from the first article I linked:
Dim i As Long
Dim j As Long
Dim msg As String
Dim arrItems() As String
ReDim arrItems(0 To ListBox1.ColumnCount - 1)
For j = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(j) Then
For i = 0 To ListBox1.ColumnCount - 1
arrItems(i) = ListBox1.Column(i, j)
Next i
msg = msg & Join(arrItems, ",") & vbCrLf & vbCrLf
End If
Next j
MsgBox msg

Related

Keeps jumping back to start of Sub as soon as it completes first iteration in the nested loop

Very new to VBA coding. I inserted a Text Box (Active Control X) in my worksheet. Wrote a code to import data from MS Access database and save that data to an array. Later I am trying to print that array in the text box for user to see. but everytime my code enters the nested part of For loop, the running iteration of sub jumps back to the start of the code. Code than runs for multiple times make multiple SQL queries and excel crashes. I am not sure why code is jumping back to start of the sub?
Private Sub TextBox1_Change()
Dim sQuery As String
Dim ReturnData() As Variant
'Clear existing data in statuses area
Dim rngClearArea As Range
Dim wsFleetio As Worksheet
Set wsFleetio = ThisWorkbook.Worksheets("Test")
Dim Farm As String
Farm = wsFleetio.Range("B1").Value
'Set rngClearArea = FindTag(wsFleetio, "$Vehicle Status", 2, 0).Resize(1000, 4)
'rngClearArea.ClearContents
'Build query
sQuery = "SELECT [KillDate], [FarmName], [LoadType] FROM Loads WHERE ([FarmName] = '" & Farm & "' AND [KillDate] >= DateAdd('yyyy', -1, Date()))"
ReturnData = GetMerlinData(sQuery)
Dim leng As Integer
leng = UBound(ReturnData, 2)
Dim FarmData(500, 2) As Variant
Dim m As Integer
For m = 0 To UBound(ReturnData, 2)
FarmData(m, 0) = ReturnData(0, m)
FarmData(m, 1) = ReturnData(1, m)
FarmData(m, 2) = ReturnData(2, m)
Next
Dim i As Long, j As Long
For i = 0 To UBound(ReturnData, 2)
For j = 0 To 2
TextBox1.Text = TextBox1.Text & FarmData(i, j) & "---"
Next j
TextBox1.Text = TextBox1.Text & vbCrLf
Next i
End Sub
After running the first iteration of j, code jumps back to start of the code. I want it to run normally but not sure what the error is
Add a second TextBox, TextBox2 and use it in the loop: TextBox2.Text = TextBox2.Text & ...

Unpredictable errors VBA microsoft word copying comments and text to excel

I tried to make a macro that takes all the comments in a word document, filters based on the comment text and then inserts them in excel with the associated text in a note.
I tried each step iteratively and I managed to copy the comments and pasting the wanted results in the same word document. Then I managed to manipulate excel by adding columns and notes.
Everything broke when I integrated the excel part with the comment extraction part. The errors were invalid procedure call for the line with rightParPos = InStr(leftParPos, comment, ")") which I hadn't touched in a while, so I tried outputting the parameters... That lead to a completely different error - an indexing error for the categories array when categoryCount was 0, which also was very strange. After that I tried removing a strange character in a string and then I suddenly got some kind of "can't connect to excel" at Set xlWB = xlApp.Workbooks.Open(FileName:=xlPath).
It seems completely random to me. I'm thinking that it might be some kind of limit or bug in the Microsoft Word environment that is causing these problems. Anyone knowing what could be a cause of these strange errors?
I couldn't find anything out of the ordinary with my code, but maybe someone on S.O. sees something that immediately looks strange. Sorry for the very messy code.
Sub Test()
Dim comment, text As String
Dim pageNr As Integer
Dim codePrefix, fileName As String
Dim newLinePos, leftParPos, rightParPos As Integer
Dim commentNr As Integer
Dim codeWorksheetIndex As Integer
Dim xlFile, xlDir, xlPath As String
'Excel'
Dim xlApp As Object
Dim xlWB As Object
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err Then
Set xlApp = CreateObject("Excel.Application")
End If
On Error GoTo 0
xlFile = "TEST"
xlDir = "My\Directory\path\" 'censored
xlPath = xlDir & xlFile
Set xlWB = xlApp.Workbooks.Open(FileName:=xlPath)
codePrefix = "a-code" 'censored
fileName = Left(ActiveDocument.Name, Len(ActiveDocument.Name)-5)
'insert a column as second column in each spreadsheet'
For sheet_index = 1 to 3
With xlWB.Worksheets(sheet_index)
.Range("B:B").Insert
.Cells(1, 2).Formula = fileName
End With
Next sheet_index
For commentNr = 1 To ActiveDocument.Comments.Count
Dim category As String
Dim categories(1 to 2) As String
Dim categoryCount As Integer
Dim numLeft, numRight as Integer
'Dim j As Integer
comment = LCase(ActiveDocument.Comments(commentNr).Range)
text = ActiveDocument.Comments(commentNr).Scope
pageNr = ActiveDocument.Comments(commentNr).Scope.Information(wdActiveEndPageNumber)
'find newline'
newLinePos = InStr(comment, vbCr)
If newLinePos = 0 Then
newLinePos = InStr(comment, vbLf)
If newLinePos = 0 Then
newLinePos = InStr(comment, vbCrLf)
if newLinePos = 0 then
newLinePos = InStr(comment, Chr(10))
if newLinePos = 0 then
ActiveDocument.Content.InsertAfter Text:="ERROR: comment " & commentNr & " misses newline!" & vbNewLine
End If
End If
End If
End If
'set to initial index for leftpar instr'
rightParPos = 1
categoryCount = 0
Do
leftParPos = InStr(rightParPos, comment, "(")
rightParPos = InStr(leftParPos, comment, ")")
If leftParPos > 0 and rightParPos > 0 Then
numLeft = rightParPos-1
numRight = numLeft - leftParPos
category = Trim(Right(Left(comment, numLeft), numRight))
categories(categoryCount) = category
categoryCount = categoryCount + 1
End If
Loop While leftParPos > 0 And rightParPos > 0
comment = fileName & " (s. " & pageNr & ")" & vbNewLine & Trim(Right(comment, Len(comment)-newLinePos))
If Instr(LCase(comment), codePrefix) = 1 Then
For categoryIndex = 0 To categoryCount-1
category = categories(categoryIndex)
If category = "category1" Then
codeWorksheetIndex = 1
ElseIf category = "category2" Then
codeWorksheetIndex = 2
ElseIf category = "category3" Then
codeWorksheetIndex = 3
End If
With xlWB.Worksheets(codeWorksheetIndex)
.Cells(commentNr+1, 2).Formula = text
.Cells(commentNr+1, 2).NoteText comment 'this only worked without =
End With
Next categoryIndex
End If
Next commentNr
End Sub
There are two critical problems with the code that were overlooked and then there was one third problem that wasn't due to the code but which also resulted in errors.
As #TimWilliams mentioned, one case where leftParPos = 0 was unhandled.
The indexing of categories was entirely wrong and faulty in the code.
The strangest error was due to having the excel file on an external harddrive that disconnected and therefore making excel not responding.

Can't retrieve specific items from a Collection in Excel VBA, even though .count is correct

I've added items to my collection, named "Questions". I know it adds items to the collection because Questions.count is the right result in various scenarios. However, I'm unable to extract the value of individual .items within the collection.
It gives me the following error: "Invalid procedure call or argument"
So obviously, there must be something basic I don't understand about collections (I only recently learned about them, please be patient with me).
I'm using the methods that I've found online, specifically:
The site https://excelmacromastery.com/excel-vba-collections/ says I should be able to do this:
"You can also use the Item Property to access an item in the collection. It is the default method of the collection so the following lines of code are equivalent:
Debug.Print coll(1)
Debug.Print coll.Item(1)"
Doesn't work for me, no idea why.
'[1] SELECT BOX
Dim SelectedBox As Long
SelectedBox = Box 'NEED TO CONVERT RESULT OF FUNCTION "BOX" TO A VARIABLE WITH TYPE LONG
'[2] TEST CRITERIA FOR QUESTION
Dim Questions As New Collection
Dim SubjectRange As Long
SubjectRange = ThisWorkbook.Sheets(cmbTopics.Text).Cells(Rows.Count, "A").End(xlUp).Row
Dim BoxMatch As Boolean
Dim ChapterMatch As Boolean
'TEST EACH QUESTION IN TOPIC (DETERMINED BY LISTBOX SELECTIONS)
For X = 2 To SubjectRange
BoxMatch = False 'SAYS WHETHER IT PASSED THE TEST
ChapterMatch = False 'SAYS WHETHER IT PASSED THE TEST
'IS QUESTION IN THE RIGHT BOX?
If ThisWorkbook.Sheets(cmbTopics.Text).Range("D" & X).Value = SelectedBox Then
BoxMatch = True
End If
'IS QUESTION IN THE RIGHT CHAPTER?
For Y = 0 To lbChapters.ListCount - 1
If _
lbChapters.List(Y) = ThisWorkbook.Sheets(cmbTopics.Text).Range("B" & X).Value And _
lbChapters.Selected(Y) = True _
Then
ChapterMatch = True
Next Y
'IF SO, THEN ADD IT TO THE LIST OF CANDIDATE QUESTIONS ("QUESTIONS")
If BoxMatch = True And ChapterMatch = True Then
Questions.Add ThisWorkbook.Sheets(cmbTopics.Text).Range("A" & X).Value
End If
Next X
'MsgBox ("Matches: " & Questions.Count)
Dim n As Long
n = RndBetween(1, Questions.Count)
MsgBox (Questions.Item(n))
I want to be able to extract the string that should be at the location specified by the code.
I saw you said that Questions.count should be greater than 0 but it would result in the error you are seeing. To be sure you should add:
If Questions.count > 0 then
MsgBox (Questions.Item(n))
Else
MsgBox ("Questions was empty")
end if
Also check that "n" is being returned as an integer.

Click all checkboxes on website

I have (in Excel, VBA) a sub that will navigate to this webpage:
http://www.nordea.dk/wemapp/currency/dk/valutaKurser
And copy the quoted rates. However, I would like to remove all the rates, and only add the ones my sub needs.
To do this, I need to check all of the boxes (to the left in the table), but the number of boxes is not constant - so I can't hardcode the boxnames.
I suppose one way to this is to extract the entire html, determine the number of rows, and then loop. But it seems very unhandy. Surely there is some smatter way, which requires less code and less storage?
You can Split() the table by vbNewLine and search for the currency in each row of the set (mind the headers).
Since the inputs are named like table:body:rows:2:cells:1:cell:check you can match the currency with the checkbox.
In practice it looks like (up to getting the element names):
Function FirstRow(myArray() As String, Optional curr As String) As Long
If curr = "" Then
curr = "*[A-Z][A-Z][A-Z]/[A-Z][A-Z][A-Z]*"
Else
curr = "*" & curr & "*"
End If
For i = LBound(myArray) To UBound(myArray)
If myArray(i) Like curr Then 'FX denoted as "XXX/XXX"
FirstRow = i
Exit Function
End If
Next i
End Function
Sub ert()
Dim myArray() As String, URLStr As String
URLStr = "http://www.nordea.dk/wemapp/currency/dk/valutaKurser"
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = False
ie.Navigate URLStr
Do Until (ie.readyState = 4 And Not ie.Busy)
DoEvents
Loop
On Error GoTo Err:
Data = ie.Document.body.innerHTML 'innerText
If False Then
Err:
Data = ie.Document.body.innerHTML
End If
myArray = Split(Data, "<tr>") 'vbNewLine) 'vbCrLf)
'For i = LBound(myArray) To UBound(myArray)
' Cells(i + 1, 1).Value2 = myArray(i)
'Next
Dim curr() As String
ReDim curr(2)
curr(0) = "DKK/NOK"
curr(1) = "EUR/SEK"
curr(2) = "USD/CHF"
For i = LBound(curr) To UBound(curr)
x = FirstRow(myArray, curr(i)) - FirstRow(myArray) + 1
MsgBox "table:body:rows:" & x & ":cells:1:cell:check"
Next i
ie.Quit
Set ie = Nothing
End Sub
I'm sorry, the vbNewLine won't cut it this time, my bad. Also, checking a named element shouldn't be that hard, had you provided your snipplet for checking all the boxes I would have even given it a shot.

Excel VB Scripting Error Handling - "object variable or with block not set" Error

I'm having some trouble with a macro for Excel. The snippet that's giving me trouble is responsible for:
1) allowing the user to select multiple column headers, one by one
2) taking the contents of each columns, in the order of header selection, and concatenating
Here's the code:
Dim concat1() As Range
Dim rng As Variant
Dim i As Variant
Dim g As Integer
Dim metalabels() As String
Dim concated As String
Dim s As Variant
lastrow = Cells(rows.Count, "A").End(xlUp).Row
i = 0
msgselect = MsgBox("Would you like to concatonate?", vbOKCancel)
On Error GoTo Errhandler
If msgselect = vbOK Then
Do
ReDim Preserve concat1(i)
Set concat1(i) = Application.InputBox("Select the headers you would like to concatonate", Default:=ActiveCell.Address, Type:=8)
msgselect = MsgBox("Another cell?", vbOKCancel)
i = i + 1
Loop While msgselect = vbOK
i = i - 1
Errhandler:
End If
ReDim metalabels(i)
For g = 0 To i
metalabels(g) = concat1(g).Text
Next
ActiveSheet.Range("a1").End(xlToRight).Offset(0, 1).Select
ActiveCell = "Situation"
For h = 1 To lastrow - 1
For g = 0 To UBound(metalabels)
concated = concated + metalabels(g) + ": " + concat1(g).Offset(h, 0).Text + " / "
Next
ActiveCell.Offset(h, 0).Value = concated
concated = ""
Next
End Sub
The problem is here:
Set concat1(i) = Application.InputBox("Select the headers you would like to concatonate", Default:=ActiveCell.Address, Type:=8)
If the user selects "Cancel," the code crashes since the loop depends on vbOK. So, I thought I'd put in an error handler, but, as it is, I get the "object variable or with block not set" error.
As you might sense, I'm still a nube with VB. Any help is greatly appreciated.
Thanks!
Place this after your End IF
If concat1(i) Is Nothing Then Exit Sub
Did you try adding if concat1(i) = false then exit sub before incrementing i?

Resources