Add to Listbox if cell value contains specific string - excel

I am trying to add data to a Listbox on a Userform, based on the value of the the Cell in column C of the range that is searched. If the cell in column C contains a certain string I would like it to be added to the Listbox.
The below code is as far as I have got but it is returning an empty Listbox with no error.
Private Sub OptionButton12_Click()
Dim I As Integer
Dim lastRow As Integer
Dim searchString As String
searchString = "LISTBOXENTRY"
With ThisWorkbook.Sheets("Sheet1")
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Plybooks.ListBox1.Clear
For I = 1 To lastRow
If Cells(I, 3).Value = searchString Then
Plybooks.ListBox1.AddItem Range("A" & I)
End If
Next I
End Sub

Try using the script below and please let me know if it works!
based on your script above, I assumed some of the dataframe dimensions. please let me know if it is not correct so I can tweak it.
I assumed you are working on first sheet (sheets(1)), and col C is the column you are using for the value check against the "searchString" variable. (if true, append the value in listbox1)
Thanks
Private Sub OptionButton12_Click()
Dim lastRow As Integer
Dim searchString As String
Dim wb As Workbook
Dim sRng As Range
Dim cel As Range
'assign current wb into wb workbook object
Set wb = ThisWorkbook
'assign str you want to search into variable
searchString = "LISTBOXENTRY"
'find last row number in colC (3) using crow function. (assuming you want to do a check on every cell listed in column C)
lastRow = crow(1, 3)
plybooks.listbox1.Clear
'assign range object using dataframe dimensions based on row 1 col C (lbound), to lastrow col3 (ubound)
With wb.Sheets(1)
Set sRng = .Range(.Cells(1, 3), .Cells(trow, 3))
End With
'loops through each cel
For Each cel In sRng
If cel.Value = searchString Then
'adds item into listbox1 if conditional statement is True
plybooks.listbox1.AddItem Item:=cel.Value
Else
End If
Next cel
End Sub
Private Function crow(s As Variant, c As Integer)
crow = Sheets(s).Cells(Rows.Count, c).End(xlUp).Row
End Function

Added cell values in ranges over multiple sheets if cell contains certain value, using the following:
Public Sub PlybookListbox()
'Clear fields before start
Plybooks.ListBox1.MultiSelect = 0
Plybooks.ListBox1.Clear
Plybooks.ListBox1.Value = ""
Plybooks.ListBox1.MultiSelect = 2
Dim AllAreas(2) As Range, Idx As Integer, MyCell As Range, TargetRange As Range
Dim lastrowFrontWing As Long
Dim lastrowNose As Long
Dim lastrowBargeboard As Long
lastrowFrontWing = Worksheets("Front Wing").Cells(Rows.Count, 2).End(xlUp).Row
lastrowNose = Worksheets("Nose").Cells(Rows.Count, 2).End(xlUp).Row
lastrowBargeboard = Worksheets("Bargeboard & SPV").Cells(Rows.Count, 2).End(xlUp).Row
Set AllAreas(0) = Worksheets("Front Wing").Range("c6:c" & lastrowFrontWing)
Set AllAreas(1) = Worksheets("Nose").Range("c6:c" & lastrowNose)
Set AllAreas(2) = Worksheets("Bargeboard & SPV").Range("c6:c" & lastrowBargeboard)
Plybooks.ListBox1.Clear
For Idx = 0 To 2
For Each MyCell In AllAreas(Idx).Cells
If InStr(1, MyCell.Value, "(FS)") > 0 Then
Plybooks.ListBox1.AddItem MyCell.Value
End If
Next MyCell
Next Idx
End Sub

Related

Use VBA to search for a list a values in column A, and when found update the cell in column B

Using VBA, I am trying to search for each value in column A of sheet 1, and match it with column A of sheet 2. If a value is found in sheet 2, update column B to "Yes"
Sheet 1
Sheet 2
So far I have:
Sub UpdateStatus()
Dim list() As Variant
Dim item As Integer
'Assign range to a variable
list = Range("A1:A" & Range("A" & Rows.Count).End(xlUp).Row)
'Loop Through Rows
For item = 1 To UBound(list)
'this is where I am stuck
Next item
End Sub
Sheet 2 should look like this afterwards:
Why loop if you can use Excel's engine?
Solution using Excel formulas
Sub Update_Status()
Dim Formula As String
Dim searchRng As Range
Dim valueRng As Range
Dim statusRng As Range
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
Set valueRng = ws1.Range("A2:A" & LastRow("A", ws1)) ' A2, since you have header
Set searchRng = ws2.Range("A1:A" & LastRow("A", ws2))
Set statusRng = valueRng.Offset(0, 1)
' =IF(COUNTIFS(Sheet2!$A$2:$A$4,Sheet1!A2),"Yes","No")
Formula = "=IF(COUNTIFS(" & _
searchRng.Address(True, True) & "," & _
valueRng.Cells(1, 1).Address(False, False) & _
"),""Yes"",""No"")"
statusRng.Formula = Formula
' In case calculation is turned off
Application.Calculate
' If we prefer hardcoded values
statusRng.Copy
statusRng.PasteSpecial xlPasteValues
Application.CutCopyMode = False ' Flush clipboard
End Sub
Private Function LastRow(Col As String, Ws As Worksheet) As Long
LastRow = Ws.Range(Col & Rows.Count).End(xlUp).Row
End Function
This seems to work:
Sub UpdateStatus()
Dim list() As Variant
Dim item As Integer
Dim FoundCell As Range
Dim SearchValue As String
Dim Sheet2 As Worksheet
Set Sheet2 = Worksheets("Sheet2")
'Assign range to a variable
list = Range("A1:A" & Range("A" & Rows.Count).End(xlUp).Row)
'Loop Through Rows
For item = 1 To UBound(list)
SearchValue = list(item, 1)
Set FoundCell = Sheet2.Range("A2:A6").Find(What:=SearchValue)
If Not FoundCell Is Nothing Then
Sheet2.Range("B" & FoundCell.Row).Value = "Yes"
Else
MsgBox (SearchValue & " not found")
End If
Next item
End Sub

Autofill with VBA in this specific flow

Please i have this issue and i am trying to achieve a solution using vba.
So cell
A1 has value John
A2-A3 blank
A4 has value Mary
A5-A9 blank
A10 has value Mike
A11-A14 blank
And A15 has value David
I wanna autofill only the blank spaces in the column A, like so:
A2-A3 the blanks will be filled with John
A5-A9 will be filled with Mary
A11-A14 with Mike.
So technically, I am auto filling the blank cells with the value from above
One version to do this is:
Sub Autofill1()
Dim ws As Worksheet
Dim lrow As Long
Dim i As Long
Set ws = Worksheets("Sheet1") 'Set your worksheet name
lrow = ws.Cells(Rows.Count, "A").End(xlUp).Row 'Find last row
For i = 1 To lrow 'Loop from 1st row to last row
If ws.Cells(i, "A").Value = "" Then 'If the cell value is blank then...
ws.Cells(i, "A").Value = ws.Cells(i - 1, "A").Value '.. copy the value from previous cell above
End If
Next i
End Sub
Another version is:
Sub Autofill2()
Dim ws As Worksheet
Dim FillRange As Range
Set ws = Worksheets("Sheet1") 'Set your worksheet name
On Error GoTo Errhand 'If range already is filled then go to error handler
For Each FillRange In Columns("A:A").SpecialCells(xlCellTypeBlanks) 'Define range in column A
If FillRange.Cells.Row <= ActiveSheet.UsedRange.Rows.Count Then 'Check if current row is smaller than last row
FillRange.Cells = ws.Range(FillRange.Address).Offset(-1, 0).Value 'Fill the empty cells with the non empty values
End If
Next FillRange
Errhand:
If Err.Number = 1004 Then MsgBox ("Column is already filled")
End Sub
It has been a long time, but if I'm not mistaken, the following should work:
Dim i As Integer, firstcell As Integer, lastcell As Integer
Dim currentValue As String
firstcell = 1
lastcell = 15
currentValue = ""
For i = firstcell To lastcell
If Cell(i,1).Value = "" Then
Cell(i,1).Value = currentValue
Else
currentValue = Cell(i,1).Value
End If
Next i
You loop through the cells and if there is nothing in them you write the last value in them. If they contain data, you update the currentValue
This solution using for each for more efficient looping.
Sub AutoFillIt()
Dim lLastRow As Long 'Last row of the target range
lLastRow = Cells(Rows.Count, "A").End(xlUp).Row 'Get number of rows
Dim rngCurrentCell As Range
Set rngCurrentCell = Range("A1") 'It will used for looping through the range
Dim rngTarget As Range
Set rngTarget = rngCurrentCell.Resize(lLastRow) 'Set the range working in
Dim vLastValue As Variant ' To store the value of the last not emplty cell
Dim v As Variant
For Each v In rngTarget 'looping through the target range
If v = "" Then 'if the cell is empty, write the last value in
rngCurrentCell.Value = vLastValue
Else 'if not empty, store the content as last value
vLastValue = v
End If
Set rngCurrentCell = rngCurrentCell.Offset(1) 'move to the next cell
Next v
End Sub

How to convert different cell value to single row using vba in excel?

I want to transfer data from one sheet to another.
My sheet1 is "form" type sheet. I have command button in it.
On pressing of command button cell value should be copied to another Sheet2.
I want every copy of value should be in one row and fixed column.
It should not be overwrite but enter in next empty row.
I am using below VBA code:
Private Sub Button1_Click()
Dim rng As Range
Set rng = Sheets("Sheet1").Range("A1,A2,B1,B2,B3")
For Each cell In rng
'here you copy to another sheet, one row lower
Sheets("Sheet2").Cells(cell.Row + 1, cell.Column).Value = cell.Value
Next cell
For x = lRow To 2 Step -1
If Range("I" & x) <> vbNullString Then Range("I" & x).EntireRow.Delete
Next x
Application.CutCopyMode = False
End Sub
Option Explicit
Sub test()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim LastRow As Long, i As Long
Dim str As String, chara As Variant
Dim rng As Range, cell As Range
With ThisWorkbook
Set ws1 = .Worksheets("Sheet1") '<- Set worksheet ws1
Set ws2 = .Worksheets("Sheet2") '<- Set worksheet ws2
End With
Set rng = ws1.Range("B1:D1,B2:B6,B8:E11") '<- Set the range you want to loop
For Each cell In rng
If str = "" Then '<- Create a string with all details
Else
str = str & "," & cell.Value
End If
Next cell
LastRow = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row
i = 1
For Each chara In Split(str, ",") '<- Split with commas
ws2.Cells(LastRow + 1, i) = chara
i = i + 1
Next chara
End Sub

Code to Generate Sequential Code with a Prefix

I have a small userform with 1 combobox, 2 textbox and 1 command button. Image is attached.
Also the image of worksheet is attached below.
Upon Initialization of Userform, combobox is populated with account heads listed in Table1.
Selection of item from combobox will populate the textbox with Account Code listed in Table1.
Group Head textbox will be entered manually.
Below is my code...
Private Sub ComboBox1_Change()
Dim ws As Worksheet, tbl As ListObject, rng As Range, cmb As ComboBox
Dim accountcode As String, rng1 As Range
Set ws = Sheets("Sheet1")
Set tbl = ws.ListObjects("Table1")
Set rng = tbl.ListColumns(1).DataBodyRange
Set rng1 = tbl.ListColumns(2).DataBodyRange
Me.TextBox1.Value = Application.WorksheetFunction.Index(rng, Application.WorksheetFunction.Match(Me.ComboBox1.Value, rng1, 0))
End Sub
Private Sub CommandButton1_Click()
Dim ws As Worksheet, tbl As ListObject, row As ListRow
Set ws = Sheets("Sheet1")
Set tbl = ws.ListObjects("Table2")
Set row = tbl.ListRows.Add
prefix = Me.TextBox1.Value & "-"
Dim NextNum As Long
Dim LastRow As Long, lRow As Long
Dim myArr() As Long
With Sheets("Sheet1")
'Find Last Row in Group Head Code Column
LastRow = .Cells(.Rows.Count, "E").End(xlUp).row
ReDim myArr(1 To LastRow)
' read all cells contents and convert them to array of numbers
For lRow = 5 To LastRow
If Mid(.Cells(lRow, 5), 4) <> "" Then
myArr(lRow) = CLng(Mid(.Cells(lRow, 5), 4))
End If
Next lRow
' find maximum value in array
NextNum = WorksheetFunction.Max(myArr)
End With
row.Range(1, 1).Value = Me.ComboBox1.Value
row.Range(1, 2).Value = prefix & NextNum + 1
row.Range(1, 3).Value = Me.TextBox2.Value
End Sub
Private Sub UserForm_Initialize()
Dim ws As Worksheet, tbl As ListObject, rng As Range, cmb As ComboBox
Set ws = Sheets("Sheet1")
Set tbl = ws.ListObjects("Table1")
Set rng = tbl.ListColumns(2).DataBodyRange
Set cmb = Me.ComboBox1
For Each rng In rng
cmb.AddItem rng.Value
Next rng
End Sub
The command button reads the value in Table 2, COlumn and 2, Generate the serial number and post the values in the Table.
What i want with the command button is, if i select any other head from the combobox, the code should read the value associated with that prefix and then generate the next serial number. Currently it is not reading the prefix.
Kindly advise what changes need to be made in my command button code to achieve this.
Thanks
Salman
I think the problem you're experiencing is that you're trying to use Sheet1 as both the output display and data storage system. Often this isn't a problem, but in your case, it's causing you to have to search Table2 each time an entry is made.
You'd be better off using a module-level variable in VBA to keep track of the incrementing number for each code. There's also no need to look up Table 1 each time a selection is made. You could either store the codes in another module-level variable or exploit the ability for ComboBoxes to have more than one column. In the sample below I've gone for the latter because it's easy to read the ListObject straight into the combo box List property - if you want to go the same route, then you'd need to change the combo box ColumnCount property to 2 and, if you want the codes to be invisible, change the ColumnWidths property to something like 0 pt;130 pt.
Your code, then, could look something like the below:
Option Explicit
Private mNextInc() As Long
Private Function IndexOf(val As String, arr As Variant) As Long
Dim i As Long
'Get array index of lookup item
For i = 1 To UBound(arr, 1)
If arr(i, 1) = val Then
IndexOf = i
Exit Function
End If
Next
End Function
Private Sub ComboBox1_Change()
Me.TextBox1.Text = Me.ComboBox1.Value
End Sub
Private Sub CommandButton1_Click()
Dim tbl As ListObject
Dim rng As Range
Dim v As Variant
With Me.ComboBox1
'Create the output array
v = Array(.Text, _
.Value & "-" & mNextInc(.ListIndex), _
Me.TextBox2.Text)
'Write new row to table
Set tbl = ThisWorkbook.Worksheets("Sheet1") _
.ListObjects("Table2")
tbl.Range.Activate
If tbl.InsertRowRange Is Nothing Then
Set rng = tbl.HeaderRowRange.Offset(tbl.ListRows.Count + 1)
Else
Set rng = tbl.InsertRowRange
End If
rng.Value = v
'Increment the digit of code
mNextInc(.ListIndex) = mNextInc(.ListIndex) + 1
End With
End Sub
Private Sub UserForm_Initialize()
Dim tbl As ListObject
Dim lRow As ListRow
Dim rng As Range
Dim inc As Long
Dim i As Long
'Populate the combobox
Set rng = ThisWorkbook.Worksheets("Sheet1") _
.ListObjects("Table1").DataBodyRange
Me.ComboBox1.List = rng.Value
'Set the increment values to 1
ReDim mNextInc(rng.Rows.Count - 1)
For i = 1 To UBound(mNextInc)
mNextInc(i) = 1
Next
'Find current max value for each group head code
Set tbl = ThisWorkbook.Worksheets("Sheet1") _
.ListObjects("Table2")
For Each lRow In tbl.ListRows
With lRow.Range
i = IndexOf(.Cells(1), rng.Value)
inc = CLng(Mid(.Cells(2), 4, Len(.Cells(2)) - 3)) + 1
End With
If inc > mNextInc(i) Then mNextInc(i) = inc
Next
'Set the combo box to first item
Me.ComboBox1.ListIndex = 0
End Sub

Counting the number of visible rows after autofilter

How do you count the number of visible/not null rows (from row 3 onwards, checking if column A is empty) after an autofilter? Right now I am only getting 26...
Full code:
Sub GetPrimaryContacts()
Dim Col As New Collection
Dim itm
Dim i As Long
Dim CellVell As Variant
'Get last row value
LastRow = Cells.SpecialCells(xlCellTypeLastCell).Row
'Loop between all rows to get unique values
For i = 3 To LastRow
CellVal = Sheets("Master").Range("F" & i).Value
On Error Resume Next
Col.Add CellVal, Chr(34) & CellVal & Chr(34)
On Error GoTo 0
Next i
' Create workbooks - Token Not activated
Call TokenNotActivated
For Each itm In Col
ActiveSheet.Range("A2:Z2").Select
Selection.AutoFilter Field:=6, Criteria1:=itm
Call CountFilterAreaRows
Next
End Sub
Here's a function that will count the visible rows in an autofiltered range, even if there are none:
Function CountFilterAreaRows(ws As Excel.Worksheet) As Long
Dim FilterArea As Excel.Range
Dim RowsCount As Long
Set ws = ActiveSheet
For Each FilterArea In ws.AutoFilter.Range.SpecialCells(xlCellTypeVisible)
RowsCount = RowsCount + FilterArea.Rows.Count
Next FilterArea
'don't count the header
RowsCount = RowsCount - 1
CountFilterAreaRows = RowsCount
End Function
To call it as a function, see the edits above. Using your example you would could call it something like this (Untested):
Sub UseIt()
Dim ws As Excel.Worksheet
Dim itm
Dim col As Collection
'... your col logic
For Each itm In col
Set ws = ActiveSheet
ActiveSheet.Range("A2:Z2").AutoFilter Field:=6, Criteria1:=itm
Debug.Print CountFilterAreaRows(ws)
Next itm
End Sub
Note that you should avoid the use of Select.
I could be wrong, because I am guessing at what your code is actually doing, but see if this gets what you want done.
For Each itm In Col
RowCount = Sheets("Master").Rows(itm.Row).Count
MsgBox RowCount
Next
Say we have an AutoFilter with the first row containing headers and nothing below the filtered table:
Sub visiCount()
Dim r As Range, n as Long
n = Cells(Rows.Count, 1).End(xlUp).Row
Set r = Range("A1:A" & n).Cells.SpecialCells(xlCellTypeVisible)
MsgBox r.Count - 1
End Sub
EDIT ............started at A1 rather than A2

Resources