Excel VBA Getting a multiple selection from a listbox - vba

I have a listbox which I set to selectmulti
I am trying to get the values of the selected items with this :
Private Sub CommandButton3_Click()
Dim lItem As Long
Dim nboc As Integer
Dim c As Integer
Range("G:G").Clear
nboc = Worksheets("BDD").Range("IQ2").Value
c = 0
For lItem = 0 To ListBox2.ListCount - 1
If ListBox2.Selected(lItem) = True Then
c = c + 1
Worksheets("Bordereau Prep").Range("G15:G" & 14 + c) = ListBox2.List(lItem)
ListBox2.Selected(lItem) = False
End If
Next
End Sub
This works as long as I have one item selected. If I have x items selected, it returns x times the first item.
Can you help me?
(I am fairly new to VBA and am trying to learn on my own)

With this line:
Worksheets("Bordereau Prep").Range("G15:G" & 14 + c) = ListBox2.List(lItem)
you override the values previously printed by this function.
In first iteration you print the value in each cell of range G15:G15 (a single cell in this case), in second iteration you print the value in each cell of range G15:G16 (so you override the value printed in first iteration) and so on.
You need to change this line like below:
Worksheets("Bordereau Prep").Range("G14").Offset(c, 0) = ListBox2.List(lItem)

Your problem is in the line:
Worksheets("Bordereau Prep").Range("G15:G" & 14 + c) = ListBox2.List(lItem)
It simply assigns the whole range to the last found value. Here is something that works for you, you may use it somehow further and change it.
Option Explicit
Sub btn()
Dim lItem As Long
Dim c As Long
Range("G:G").Clear
For lItem = 0 To Worksheets("Bordereau Prep").ListBox2.ListCount - 1
If Worksheets("Bordereau Prep").ListBox2.Selected(lItem) = True Then
c = c + 1
Worksheets("BDD").Cells(15 + c, 7) = Worksheets("Bordereau Prep").ListBox2.List(lItem)
'Worksheets("Bordereau Prep").Range("G15:G" & 14 + c) = Worksheets("Bordereau Prep").ListBox2.List(lItem)
Worksheets("Bordereau Prep").ListBox2.Selected(lItem) = False
End If
Next lItem
End Sub
Last but not least, you try not to use Integers in VBA, but longs. Enjoy it!

Related

How to rename a variable (Loops to fill multiple matrices)

Im trying to fill multiple matrices according to inputs from a userform.
Right now i have to create 5 matrices but i want this to be able to change in the future, so i want to create the variables "on the fly" in my loop. I basically want to Create Matrix1, Matrix2, Matrix3 ... Matrixn, but i can't figure how to do it. Any Ideas ?
Following you can see the script --> The two last lines are totally wrong (i know it) but i just added them in hope that you understand what i want to do :)
PS: And most important i should be able to then look to Matrix1(i,j),..., Matrixn(i,j) values easily
Looking Forward your help <3
'FicheCalcul ----------------------------------------------------------------------------------------------------
Dim Temp4 As String
Dim Temp5 As String
Dim MatrixTemp(3 - 1, 5 - 1) As Double 'm-1,x-1
For i = 1 To 5 'n
For j = 0 To 3 - 1 'm-1
For k = 0 To 5 - 1 'X-1
Temp4 = j & "C" & i
Temp5 = Temp4 & k
If UserForm1.Controls(Temp5) = False Then
MatrixTemp(j, k) = ""
Else
If UserForm1.Controls(Temp5) = True Then
MatrixTemp(j, k) = k - 2 ' -2 -1 0 1 2
End If
End If
Next k
Next j
Dim ("Matrix"&i)(3-1,5-1) As Double
("Matrix"&i) = MatrixTemp
Next i
You cannot have variable variable names. Therefore you need to use arrays.
Option Explicit
Sub example()
Dim MatrixTemp(4, 5) As Double
'do your matrix stuff here
MatrixTemp(0, 0) = 1
MatrixTemp(0, 1) = 2
MatrixTemp(0, 2) = 3
Dim Matrix(4) As Variant 'create an array of 5 matices
Matrix(0) = MatrixTemp 'fill your temp matrix into the first matrix
Debug.Print Matrix(0)(0, 2) 'outputs 3
End Sub

Find the first empty cell after a text in a row

I'm working on a project and need at the moment to find the first empty cell just after text cells in a row in Excel. To clarify, let me explain to you what I'm lookng for with this screenshot
I want to write a code to return for me for like an example in the case of the 20th row the number of column of the cell E20 even if the first empty cell is A20 but like I said, i want the first empty cell juste after the last "not empty" one.
for the 21th row the result will be C21, the 22th row it will be F22 and there you go
Here's the code I wrote but for some reason it doesn't work, please help.
Function emptyCell(ws As Worksheet, ligne As Integer)
Dim m, p, n As Integer
Dim suite(700) As Integer
For k = 0 To 700
suite(k) = 0
Next
emptyCell = 0
i = 1
Do Until suite(i) = 0 And suite(i - 1) = 1
If ws.Cells(ligne, i) <> "" Then
suite(i) = 1
End If
i = i + 1
emptyCell = emptyCell + 1
Loop
End Function
Sub test()
Dim d As Integer
empty_cell = emptyCell(Sheets("tmp"), 2)
MsgBox (empty_cell)
End Sub
The logic of my code is to assign 0 for empty cells and 1 in the other caase, run a test to find the first 1-0 that's gonna appear in my array and get the column order from the order of this "1"
I know I'm not that clear cause I didnt want it to make it a long post and english is not my first language.
Thanks in advance
All if you want to get the first empty cell after the last non empty cell, why not try it like this?
Function emptyCell(ws As Worksheet, Row As Long) As Range
Set emptyCell = ws.Cells(Row, ws.Columns.Count).End(xlToLeft).Offset(, 1)
End Function
Sub Test()
Dim empty_cell As Range
Set empty_cell = emptyCell(Sheets("tmp"), 20)
MsgBox empty_cell.Address
End Sub

Looping to find letters in a column on VBA

My macro is to send emails for some clients. It sends the email only if there is a X at one of the lines of the column B, so then it sends the whole line to the client by creating a new sheet that goes attached to the client on the email.
The problem is that I need to create a loop to count all the columns that contain the letter X, because this macro is counting only the first line that contains the letter X and then the other ones don't go to the new sheet and consequently it doesn't go to the client. Everything is OK in my macro, despite of the counter. When i run it, just the first line that contains the X goes to the client, and the others don't. Can you guys help me?
Code:
LinhaInicio = 1
While Workbooks(planilha).Sheets("Boletas").Cells(LinhaInicio, 2) <> "X"
LinhaInicio = LinhaInicio + 1
Wend
LinhaFim = LinhaInicio
While Workbooks(planilha).Sheets("Boletas").Cells(LinhaFim, 2) = "X"
LinhaFim = LinhaFim + 1
Wend
LinhaFim = LinhaFim - 1
RangeInicio = Workbooks(planilha).Sheets("Boletas").Cells(LinhaInicio, 26).Address
RangeFim = Workbooks(planilha).Sheets("Boletas").Cells(LinhaFim, 34).Address
Set RangeCopiar = ActiveSheet.Range(RangeInicio, RangeFim)
Maybe Try something like this:
Dim vArr As Variant
Dim LinhaFim As Long
Sub mainLoop()
'put all values into variant array vArr
vArr = Workbooks(planilha).Sheets("Boletas").UsedRange
For i = LBound(vArr) To UBound(vArr)
If vArr(i, 2) = "X" Then
Nestedloops (i) 'initiate nested loops
i = LinhaFim 'artificially increment counter
End If
Next i
End Sub
Sub Nestedloops(LinhaIncio As Long)
With Workbooks(planilha).Sheets("Boletas")
LinhaFim = linhaInicio
While vArr(LinhaFim, 2) = "X"
LinhaFim = LinhaFim + 1
Wend
LinhaFim = LinhaFim - 1
RangeInicio = .Cells(LinhaInicio, 26).Address
RangeFim = .Cells(LinhaFim, 34).Address
Set RangeCopiar = ActiveSheet.Range(RangeInicio, RangeFim)
'email code goes here
End With
End Sub
Tim could come up with something better though might want to see what he comes up with
you wanna search the X letter to columns or rows, sorry I didn't understand what you try to say. You want to create a loop to count all the X letter for every row and column or only for every row from a column?
here is how you define an array:
Dim timelinessSheet, o As Variant
timelinessSheet = Worksheets("your_sheet_name").Range("A2:X" & Worksheets("your_sheet_name").Cells(Worksheets("your_sheet_name").Rows.Count, "B").End(xlUp).Row).Value
and then your code
dim i as long
for i=2 to ubound (timelinessSheet,1)
if timelinessSheet(i,2)= X then
Your_condition
end if
next I

Loop through Excel Ranges Filling Combobox VB.Net

I have a program that needs to iterate through a very large excel range, to combine two ranges into one combo box value. I have the following code to do so, but all it does is iterate the first value five times. If I remove the first FOR loop, then it simply only returns the first value and never completes. Any suggestions on what I can do to polish this code up and get it working?
Dim i As Integer
If TenantBox.SelectedItem = "CNS" Then
WFMBook.Workbooks.Open("C:\Schedule.xlsx")
For i = 0 To 5 Step +1
For Each CNSCell In WFMBook.Range("A3:A1441").Cells
f = CNSCell.Value.ToString
Next
For Each tst In WFMBook.Range("B3:B1441").Cells
l = tst.Value.ToString
Next
ComboBox1.Items.Add(f + " " + l)
If (i = 5) Then
Exit For
End If
Console.WriteLine(i)
Next
End If
Try this, just change the x to 1 if VBA is 1 based.
If TenantBox.SelectedItem = "CNS" Then
WFMBook.Workbooks.Open("C:\XHSchedule.xlsx")
Dim colCount = WFMBook.Range("A3:A8").Cells.Count
For x = 1 To colCount Step +1
For Each CNSCell In WFMBook.Range("A3:A8").Cells
f = WFMBook.Range("A3:A8").Cells(x).Value.ToString
l = WFMBook.Range("B3:B8").Cells(x).Value.ToString
Next
ComboBox1.Items.Add(f + " " + l)
Next
End If

Search a column and delete another row if phrase found VBA

I have Column A and what I'm looking to do is search for a phrase, say "test" and then if this phrase is found delete 2 rows after that.
I can see how to delete a row if the phrase is found in that row but not how to delete another row.
Try something like this:
Public Sub DeleteRowsIfFound()
Dim originCell As Range, numberOfRowsToDelete As Integer
Dim blankCellLimit As Integer, numberOfBlankCells As Integer
Dim label As String, index As Long, n As Integer
Set originCell = Me.Range("A1")
blankCellLimit = 5
numberOfRowsToDelete = 2
index = 0
label = "test"
Do
If originCell.Offset(index, 0).Value = label Then
For n = 0 To numberOfRowsToDelete - 1
originCell.Offset(index + 1, 0).EntireRow.Delete
Next
ElseIf originCell.Offset(index, 0).Value = "" Then
numberOfBlankCells = numberOfBlankCells + 1
End If
index = index + 1
Loop While numberOfBlankCells < blankCellLimit
End Sub
This starts searching down column A starting at cell A1, and if it finds a cell with the value "test" then it will delete the next two rows following it.