VBA Looping through checkboxes and getting its name from excel table - excel

As you can see above, I have a table in a Excel sheet where indication A can have product 1, product 2 and so forth (The prods names are all different depending on the indication, this is just for simplicity!).
In my userform a similar format is presented. I want to basically match the indication name on my excel sheet with the indication name in my userform. If they match, then Product 11 gets A's Prod 1 name, Product 12 gets A's Prod 2 name and so forth.
I've tried the following, but I'm just starting using VBA so I'm sure it probably doesn't even make sense.
Dim code_ind As String
Dim sel_ind As String
Dim chkbx As Control
Dim labx As Control
Dim i As Integer
Dim col_value As Integer
Dim row_value As Integer
For i = 1 To 8
For j = 1 To 4
For row_value = 4 To 11
col_value = 0
Set chkbx = Me.Controls("seg_l_selInd_" & i)
Set labx = Me.Controls("seg_cb_selInd_" & i & j)
sel_ind = tWb.Worksheets("LALALA").Columns(2).Find(what:=chkbx)
If code_ind = sel_ind Then
labx.Name = tWb.Worksheets("LALALA").Cells(row_value, 3 + col_value)
col_value = col_value + 1
End If
Next row_value
Next j
Next i
Is there any way I can do this? I know I could just write the names manually, but I need my tool to be as flexible as possible. Ideally, if more information is added into the excel table, the userform will automatically update.

Please check the next way. I tried thinking your project in this way:
The form in the next example must be named frmChkBox. The check boxes on the form will have names like "CheckBox11", "CheckBox12" and so on, first digit after "CheckBox" string being the row and the next one the column. If you appreciate that your real situation will exceed one digit number for the row number, they can be separated by "_", or something else. You can also create the check boxes on the flay.
a. Please paste in the form code module the next code lines:
Option Explicit
Private ChkBColl As New Collection
Private ChkB() As New ChkBoxChClss
Private Sub UserForm_Initialize()
Dim ws As Worksheet, rng As Range, iRow As Long, iCol As Long
Dim ctrl As MSForms.Control, ext As String, arrUsed, k As Long
ReDim ChkB(32)
ReDim arrUsed(Me.Controls.count)
Set ws = Sheets("INDICATION-PRODUCT")
Set rng = ws.Range("B2:E9")
For iRow = 1 To 8
For iCol = 1 To 4
For Each ctrl In Me.Controls
If TypeOf ctrl Is MSForms.CheckBox Then
If IsError(Application.Match(ctrl.Caption, arrUsed, 0)) Then
ext = Right(ctrl.Caption, Len(ctrl.Caption) - 8)
If left(ext, 1) = iRow And Right(ext, 1) = iCol Then
ctrl.Tag = rng.cells(iRow, iCol).Address
ctrl.Caption = rng.cells(iRow, iCol).Value
arrUsed(k) = ctrl.Caption: k = k + 1
ChkBColl.Add ctrl, ctrl.Name
Set ChkB(k).chkBEvent = ctrl
End If
End If
End If
Next
Next iCol
Next iRow
End Sub
Public Sub DoSomething(chk As MSForms.CheckBox)
Dim ws As Worksheet
Set ws = Sheets("INDICATION-PRODUCT"): ws.Activate
If chk.Value = True Then
ws.Range(chk.Tag).Select 'do whatever needed with the cell...
Else
ws.Range("A1").Select
End If
End Sub
Each check box Tag will receive the associated cell address.
In order to automatically allocate the same event to all of them, a simple class wrapper (named `ChkBoxChClss') will be created. It will identify the clicked check box and send the object to a form sub, where to be processed as needed. Please, paste the next code in the class:
Option Explicit
Public WithEvents chkBEvent As MSForms.CheckBox
Private Sub chkBEvent_Change()
frmChkBox.DoSomething chkBEvent
End Sub
You can use the Public Sub DoSomething to deal with the check box being clicked. Now, clicking a check box, if its value is True the correspondent cell will be selected. If False, the "A1" cell will be selected. You can do whatever you need.

I was finally able to solve it!
The table I have on my worksheet (Image 1) has the indication column that corresponds to the indication values on my userform. For each indication, there are several products.
I want my tool to be as flexible as possible, so I needed to match the indication name and for each checkbox in my userform I would obtain it's name from the table.
For example: Indication A, Prod 1 = Prod 1 (Checkbox.Name = Cell(x,y))
This is the code that I'm using:
Dim code_ind As String
Dim sel_ind As String
Dim chkbx As Control
Dim labx As Control
Dim i As Integer
Dim j As Integer
Dim col_value As Integer
Dim row_value As Integer
For i = 1 To 8
Set chkbx = Me.Controls("seg_l_selInd_" & i)
sel_ind = tWb.Worksheets("INDICATION-PRODUCT").Columns(2).Find(what:=chkbx)
If chkbx = sel_ind Then
col_value = 0
While tWb.Worksheets("INDICATION-PRODUCT").Cells(i + 3, 3 + col_value) <> ""
For j = 1 To 4
Set labx = Me.Controls("seg_cb_selInd_" & i & j)
labx.Caption = tWb.Worksheets("INDICATION-PRODUCT").Cells(i + 3, 3 + col_value)
col_value = col_value + 1
Next j
Wend
End If
Next i
Does it make sense to you?
Is there any way to make my code more flexible? For example, I'm assuming there are 8 indications (i = 1 to 8), but realistically there could be more in the future.

Related

Fill cells with values from another sheet using For Loop VBA

I have a set of information in the same column (H27:O27) in one sheet ("P1-FR1") and would like to paste individual values to another sheet (AQ6:AX6) ("Übersicht GESAMT")
I'm trying to use a For loop but the values just copy one after the other (in the same cell) instead of copying one in each cell. This is my code:
Sub CopyValues()
Dim i As Long
Dim j As Long
Dim Wert As Long
For i = 8 To 14
Wert = Sheets("P1-FR1").Cells(27, i)
For j = 43 To 50
Sheets("Übersicht GESAMT").Cells(6, j) = Wert
Next j
Next i
End Sub
You don't need a double For loop in this case at all. A simple .Value copy will work. The code below shows two examples with different ways to accomplish what you want. (TIP: it always helps me to be VERY clear on how I name the variables, it helps to keep track of where all the data is coming and going)
Option Explicit
Sub CopyTheValues()
Dim datenQuelle As Range
Dim datenZiel As Range
Set datenQuelle = ThisWorkbook.Sheets("P1-FR1").Range("H27:O27")
Set datenZiel = ThisWorkbook.Sheets("Übersicht GESAMT").Range("AQ6:AX6")
'--- method 1 - works because the ranges are the same size and shape
datenZiel.Value = datenQuelle.Value
'--- method 2 - for loops
' index starts at 1 because the Range is defined above
' (and we don't care what rows/columns are used)
Dim j As Long
For j = 1 To datenQuelle.Columns.Count
datenZiel.Cells(1, j).Value = datenQuelle.Cells(1, j).Value
Next i
End Sub
Copying By Assignment
Option Explicit
Sub CopyValuesNoLoop()
ThisWorkbook.Worksheets("Übersicht GESAMT").Range("AQ6:AX6").Value _
= ThisWorkbook.Worksheets("P1-FR1").Range("H27:O27").Value
End Sub
Sub CopyValuesQuickFix()
Dim j As Long: j = 43
Dim i As Long
For i = 8 To 14
ThisWorkbook.Worksheets("Übersicht GESAMT").Cells(6, j).Value _
= ThisWorkbook.Worksheets("P1-FR1").Cells(27, i).Value
j = j + 1
Next i
End Sub
The nesting of the for loops is causing your issue. It is causing each cell from the first sheet to be copied to all cells on the second sheet.
You only need one loop to perform the copy. Something like this should work.
Sub CopyValues()
Dim i As Long
For i = 8 To 15
Sheets("Übersicht GESAMT").Cells(6,i+35) = Sheets("P1-FR1").Cells(27,i)
Next i
End Sub

Comparing 2 Pair Data with Loop in Ms Excel VBA

Is anyone can help me, pls take a look at the picture i attached.
I want to compare 2 pair of data from 2 different excel file, Station (left file column B) with Station (right file column A) AND Time (left file row 1) with Tendancy (right file Column F).
The left file is the report that im about to finished, the right file is the reference data. If the station and the time data is match each other, it will filled with "1", if not it will stay empty.
The data will start filling from cell C2 until Z32. Im stuck with FOR and IF looping i used. And here's the example:
Cell C2 will filed with "1" bcs there is station 2000001 (cell A2) at 00UTC (cell F2) on the right file.
Cell E2 will stay empty bcs there is station 2000001 BUT NOT at 02UTC on the right file.
Cell C3 will stay empty bcs there is station 2000002 BUT NOT at 00UTC on the right file.
Dim countSM As Long
Dim countSS As Long
Dim countWM As Long
Dim countWS As Long
Dim resultCol As Long
Dim resultRow As Long
Dim lastSM As Long
Dim lastSS As Long
Dim lastWM As Long
Dim lastWS As Long
Dim lastRCol As Long
Dim lastRRow As Long
lastSM = wb1.Sheets("Sheet1").Cells(Rows.count, 1).End(xlUp).Row
lastSS = wb2.Sheets("Worksheet").Cells(Rows.count, 1).End(xlUp).Row
lastWM = wb1.Sheets("Sheet1").Cells(1, Columns.count).End(xlToLeft).Column
lastWS = wb2.Sheets("Worksheet").Cells(Rows.count, 1).End(xlUp).Row
lastRCol = wb1.Sheets("Sheet1").Cells(1, Columns.count).End(xlToLeft).Column
lastRRow = wb1.Sheets("Sheet1").Cells(Rows.count, 1).End(xlUp).Row
For countSM = 2 To lastWM
For countSS = 2 To lastWS
If wb1.Sheets("Sheet1").Cells(countSM, "B") = wb2.Sheets("Worksheet").Cells(countSS, "A") Then
For countWM = 3 To lastWM
For countWS = 2 To lastWS
If wb1.Sheets("Sheet1").Cells(1, countWM) = wb2.Sheets("Worksheet").Cells(countWS, "F") Then
For resultRow = 2 To lastRRow
For resultCol = 3 To lastRCol
wb1.Sheets("Sheet1").Cells(resultRow, resultCol) = "1"
Next resultCol
Next resultRow
Next countSS
ElseIf wb1.Sheets("Sheet1").Cells(1, countWM) <> wb2.Sheets("Worksheet").Cells(countWS, "F") Then
wb1.Sheets("Sheet1").Cells(resultRow, resultCol) = ""
Next countWM
End If
Next countSS
ElseIf wb1.Sheets("Sheet1").Cells(countSM, "B") <> wb2.Sheets("Worksheet").Cells(countSS, "A") Then
wb1.Sheets("Sheet1").Cells(resultRow, resultCol) = ""
Next countSM
End If
I made a code that may work for you. Just count how many rows got the station and UTC value you want to check. If the answer is zero, leave the cell empty. If not, then return 1.
My code is designed on same workbook but it can be adapted yo work with 2 different workbooks easily.
My fake dataset:
My code:
Sub test()
'<------>
'
'
'
'
'YOUR CODE TO OPEN BOTH FILES
'
'
'
'<---->
Dim LeftSheet As Worksheet
Dim RightSheet As Worksheet
Dim MyData As Range 'range to store the data (right file)
Dim LR As Long 'Last row of left file, column Station
Dim LC As Long 'Lastcolumn of left file, (whatever UTC it is)
Dim i As Long
Dim zz As Long
Dim MiF As WorksheetFunction
Set MiF = WorksheetFunction
Dim MyStation As String
Dim MyUTC As String
'Probably you'll need just to adjust references to worksheets from different workbooks
Set LeftSheet = ThisWorkbook.Worksheets("Destiny")
Set RightSheet = ThisWorkbook.Worksheets("Source")
'we store all data into array
Set MyData = RightSheet.Range("A1").CurrentRegion
'data starts at index 2, and we want data from columns 1 and 6 on the range
'Columns 1 and 6 mean columns A and F
'I guess maybe you'll need to adapt this too.
With LeftSheet
LR = .Range("B" & .Rows.Count).End(xlUp).Row
LC = .Cells(1, .Columns.Count).End(xlToLeft).Column
'we count how many rows got the station and tendancy value (intersection) on the right file
' if the count is 0, do nothing. If not zero, return 1 on the cell
'our references will be always at column 2 and row 1
For i = 2 To LR Step 1 'we start at row 2 on left file
MyStation = .Range("B" & i).Value
For zz = 3 To LC Step 1 'we start at column 3, that means column C
MyUTC = .Cells(1, zz).Value
If MiF.CountIfs(MyData.Columns(1), MyStation, MyData.Columns(6), MyUTC) <> 0 Then .Cells(i, zz).Value = 1
Next zz
Next i
End With
'clean variables
Set MyData = Nothing
Set LeftSheet = Nothing
Set RightSheet = Nothing
End Sub
Output after executing code:
Give this solution a try:
Option Explicit
Private Type TWorksheetData
WrkSheet As Worksheet
LastRow As Long
LastColumn As Long
End Type
Sub CopyCompare()
'Organize the variables by referenced worksheet
Dim worksheetData As TWorksheetData
Dim sheet1Data As TWorksheetData
'your solution will provide separate Workbooks for the code below
'ActiveWorkbook (in my case) had both worksheets in order to develop the solution
sheet1Data = SetupWorksheetData(Application.ActiveWorkbook, "Sheet1", sheet1Data)
worksheetData = SetupWorksheetData(Application.ActiveWorkbook, "Worksheet", worksheetData)
Dim refData As Dictionary
Set refData = New Dictionary
'Load the reference data (key = station, value = collection of UTCs)
Dim station As Long
Dim countRow As Long
For countRow = 2 To worksheetData.LastRow
station = CLng(worksheetData.WrkSheet.Range("A" & CStr(countRow)).Value)
If Not refData.Exists(station) Then
refData.Add station, New Collection
End If
refData(station).Add worksheetData.WrkSheet.Range("F" & CStr(countRow)).Value
Next countRow
'Load the UTC header columns from Sheet1
Dim outputMap As Dictionary '(key = UTCXX, value = column Number)
Set outputMap = LoadUTCHeaderColumns(sheet1Data)
'Operate on the Sheet1 data to set the value
For countRow = 2 To sheet1Data.LastRow
station = CLng(sheet1Data.WrkSheet.Range("B" & CStr(countRow)).Value)
Dim utcRef As Variant
If refData.Exists(station) Then
Dim utc As Variant
For Each utc In refData(station)
If InputSheetHasUTCEntry(utc, outputMap) Then
sheet1Data.WrkSheet.Cells(countRow, outputMap(utc)) = "1"
End If
Next
End If
Next countRow
End Sub
Private Function InputSheetHasUTCEntry(ByVal utc As String, ByVal outputMap As Dictionary) As Boolean
InputSheetHasUTCEntry = False
Dim utcRef As Variant
For Each utcRef In outputMap.Keys
If utc = utcRef Then
InputSheetHasUTCEntry = True
Exit Function
End If
Next utcRef
End Function
Private Function LoadUTCHeaderColumns(ByRef sheetData As TWorksheetData) As Dictionary
Set LoadUTCHeaderColumns = New Dictionary
Dim columnHeader As String
Dim outputCol As Long
For outputCol = 1 To sheetData.LastColumn
columnHeader = sheetData.WrkSheet.Cells(1, outputCol).Value
If InStr(columnHeader, "UTC") > 0 Then
LoadUTCHeaderColumns.Add columnHeader, outputCol
End If
Next outputCol
End Function
Private Function SetupWorksheetData(ByVal wb As Workbook, ByVal sheetName As String, ByRef wrksheetData As TWorksheetData) As TWorksheetData
SetupWorksheetData = wrksheetData
Set SetupWorksheetData.WrkSheet = wb.Sheets(sheetName)
SetupWorksheetData.LastRow = SetupWorksheetData.WrkSheet.Cells(Rows.Count, 1).End(xlUp).Row
SetupWorksheetData.LastColumn = SetupWorksheetData.WrkSheet.Cells(1, Columns.Count).End(xlToLeft).Column
End Function
Solution comments:
Loads static reference data from from sheet Worksheet (recommend a different sheet name)
Loads static column number information from Sheet1
There are lots of variables holding similar data for each worksheet used. This indicates an opportunity for using a UserDefinedType (TWorksheetData in this case). This organizes and reduces the number of variables to declare and track.
#1 and #2 uses a Dictionary to retain and correlate static information (requires adding a reference to the Microsoft Scripting Runtime).
Other comments:
(Best Practice) Always declare Option Explicit at the top of modules. Forces all variables used to be declared.
(Best Practice) Don't Repeat Yourself (DRY) - there is a lot of repeated expressions in the original code. This is especially important with Strings. More could be done with the solution provided, but (for example) you will notice that the worksheet name strings only appear once.

How to create multiple variables in a loop and assign values in VBA

I have an Excel spreadsheet with several thousand lines of data which is broken up into multiple sections based on the Manager. I have created coding that hides any lines with a zero value within a range for the individual sections, but they run slow and I'm not sure if there is a faster way to accomplish the same result. Here is what I have so far:
Option Explicit
Public shp As Single
Public r1 As Single
Public r23 As Single
Public sFind as String
1st part of the coding, which designates the rows to be looped through within the manager group. I have a button for each Manager and a Sub Button#_Click() to go with each section of data. Below is an example for Button#1, each look the same other than row numbers being different.
Sub Button1_Click()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
shp = 6
r1 = 14
r23 = 36
Call Button_Macro
Application.ScreenUpdating = True
Application.DisplayAlerts = True
The above code calls the following code to run:
Sub Button_Macro()
Dim r as Single
Dim x as Single
Dim i as Single
Dim MyArray as Variant
Dim ShpName as String
ShpName = "Rounded Rectangle " & Shp
ActiveSheet.Shapes.Range(ShpName).Select
sFind = Selection.ShapeRange(1).TextFrame2.TextRange.Characters.Text
If sFine = "-" Then
ActiveSheet.Shapes.Range(Array(ShpName)).Select
Selection.ShapeRange(1).TextFrame2.TextRange.Characters.Text = "+"
Rows(r1 & ":" & r23).Hidden = True
Else
ActiveSheet.Shapes.Range(Array(ShpName)).Select
Selection.ShapeRange(1).TextFrame2.TextRange.Characters.Text = "-"
Rows(r1 & ":" & r23).Hidden = False
MyArray = Range(Cells(r1,4), Cells(r23,6)).Value
r = 1
x = r1
For i = r1 to r23
If MyArray(r,1) + MyArray(r,2) + MyArray(r,3) = 0 Then
Rows(x).EntireRow.Hidden = True
End If
x = x + 1
r = r + 1
Next i
End If
Cells(r1 - 1, 2).Select
End Sub
Next to each section of data there is a button that has a + when all rows in the Manager's section are hidden, then when you click the button it runs the code and changes the button text to - and only shows rows with values greater than zero. When I click the button, it takes roughly 10 seconds for the code to run. I know that doesn't sound like much, but people expect that when they click the button the rows with values should appear immediately, not 10 seconds later so I'm trying to find out if there is a faster way of coding this. Thanks.
Check if there are formulas relying on visible cells only then turn Calculation to manual in the beginning and back to automatic in the end. Otherwise it will re-calculate on every row hide.
Note that instead of using these Public variables
Public shp As Single
Public r1 As Single
Public r23 As Single
Public sFind as String
you should give them as parameters of your procedure. Also row numbers are of type Long not Single and sFind should be a local variable of Button_Macro and not Public:
Option Explicit
Public Sub Button_Macro(ByVal shp As Long, ByVal r1 As Long, ByVal r23 As Long)
Dim sFind as String
'your code here …
End Sub
And call it like
Public Sub Button1_Click()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Button_Macro shp:=6, r1:=14, r23:=36
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
In this part I would recommend to stop using multiple counters as they all depend on each other the following
r = 1
x = r1
For i = r1 to r23
If MyArray(r,1) + MyArray(r,2) + MyArray(r,3) = 0 Then
Rows(x).EntireRow.Hidden = True
End If
x = x + 1
r = r + 1
Next i
can be written as
Dim i As Long 'i must be long too
For i = r1 to r23
If MyArray(i-(r1-1),1) + MyArray(i-(r1-1),2) + MyArray(i-(r1-1),3) = 0 Then
Rows(i).EntireRow.Hidden = True
End If
Next i
Please replace your loop with this one. Yours is convoluted and runs many, many times.
For R = R1 To R23
Myarray = Range(Cells(R, 4), Cells(R, 6)).Value
If MyArray(1, 1) + MyArray(1, 2) + MyArray(1, 3) = 0 Then
ActiveSheet.Rows(R).EntireRow.Hidden = True
End If
Next R
Note that row and column numbers should be contained in variables of Long data type. That's sufficient because they will never contain fractions which Longs can't handle.
I have worked out another answer for you which is more comprehensive. It's contained in a single procedure which is called by all the buttons. Depending upon the position of the button it works out which rows to hide, even if you add or delete rows in the future. You can also add or delete buttons.
Sub ShowHide_Click()
' 020
Dim Ws As Worksheet
Dim Button As Shape
Dim ButtonName As String, NextName As String
Dim ButtonID As Integer
Dim ShowRows As Boolean ' True if "+" was clicked
Dim Rstart As Long, Rend As Long ' rows to hide
Dim RowRange As Range
Dim Arr As Variant
Dim R As Long
Set Ws = ActiveSheet ' better name the sheet
' get the name of the button that was pressed
ButtonName = Application.Caller
Set Button = Ws.Shapes(ButtonName)
' read and reset the button
With Button.TextFrame.Characters
ShowRows = .Text = "+"
.Text = IIf(ShowRows, "-", "+")
End With
' assume the first row to hide will be 1 row below the button
Rstart = Button.TopLeftCell.Row + 1
' extract the ID from the name
Do
NextName = Right(ButtonName, ButtonID)
ButtonID = ButtonID + 1
If ButtonID >= Len(ButtonName) Then Exit Sub
If Not IsNumeric(Right(ButtonName, ButtonID)) Then Exit Do
Loop
ButtonID = Val(NextName)
' name the next button in serial sequence
NextName = Trim(Left(ButtonName, Len(ButtonName) - Len(NextName))) _
& Str(ButtonID + 1)
With Ws
' this test will return False if Shape(NextName) doesn't exist
If .Shapes(NextName).Name = NextName Then
' this presumes that the last row to be hidden will be the one
' just above the next button's TopLeftCell.
Rend = .Shapes(NextName).TopLeftCell.Row - 1
Else
' the specified button wasn't found
' change column is column B isn't dominant in this regard
Rend = .Cells(Ws.Rows.Count, "B").End(xlUp).Row
End If
' set the range attached to the button
Set RowRange = .Range(.Rows(Rstart), .Rows(Rend))
' show or hide rows
RowRange.Rows.EntireRow.Hidden = Not ShowRows
If ShowRows Then
For R = Rstart To Rend
Arr = Ws.Range(Cells(R, 4), Cells(R, 6)).Value
Ws.Rows(R).EntireRow.Hidden = (Arr(1, 1) + Arr(1, 2) + Arr(1, 3) = 0)
Next R
' ' consider this alternative (Delete Dim Arr if you choose this)
' For R = Rstart To Rend
' Ws.Rows(R).EntireRow.Hidden = (Application.Count(Ws.Range(Cells(R, 4), Cells(R, 6))) = 0)
' Next R
End If
.Cells(Rstart, "B").Select
End With
End Sub
I have added a lot of comments to the code to show how the code works and how to adjust it to work with your worksheet. However, there are a few condition which your worksheet must meet.
The buttons must all be of the same type, like "Rounded Rectangle".
They must be numbered consecutively. The numbers must not start from 1 (though I can't see why they shouldn't) but they must be numbered consecutively top to bottom. You can't add a button in the middle, like 1, 2, 3, 7, 4, 5, 6. The numbering must be 1, 2, 3, 4, 5, 6, 7.

How do you add a variable.value as the parameter of range()?

I'm trying to merge the first three empty rows and write Activity# in the three merged cells. I can't even figure out how to select 3 custom cells to get them ready for merging. I checked everywhere online but range(A1:B2) is always given a definitive range. How do I write for example: range(variable_A1:variable_B2)?
This is my code so far:
Private Sub OKButton_Click()
'Make Sheet1 active
Sheet1.Activate
Dim beginning
Dim ending
Dim selection
beginning = Cells(empty_row.Value, 2)
ending = Cells(empty_row.Value + 2, 2)
'this is supposed to select 3 cells, but it doesn't work
selection = Range("beginning:ending").Select
'figure out how to merge cells below
Cells(empty_row.Value, 2).Value = "Activity" & Activity_number.Value
Dim i As Integer
For i = 1 To nb_subs.Value
Cells(empty_row.Value + i + 2, 2).Value = "Sub-Activity" & i
Next i
Private Sub OKButton_Click()
Dim beginning As Range
Dim ending As Range
Dim selection As Range
With Sheet1
Set beginning = .Cells(empty_row.Value, 2)
Set ending = .Cells(empty_row.Value + 2, 2)
'this is supposed to select 3 cells, but it doesn't work
Set selection = .Range(beginning, ending)
selection.Merge
selection.Value = "Activity" & Activity_number.Value
Dim i As Integer
For i = 1 To nb_subs.Value
.Cells(empty_row.Value + i + 2, 2).Value = "Sub-Activity" & i
Next i
End With

Excel (VBA, Userform) How can I extra the data from Listbox to a specific cell?

Here is what I have so far, there is only one column of data, and I want to extract it and write it down in a specific cell (like: sheet14.cells(45,2).value)
Thanks for your help.
Assuming what you mean is you want to extract data from a ListBox to a specific cell
Here is my answer
Inside the code of the userform put a button for the function
Private Sub CommandButton1_Click()
Dim i 'to store the item of the list
Dim j 'Just a counter
j = 0 'Ini the counter
For Each i In Me.ListBox1.List 'Ini the for loop
j = j + 1 'Add one to the counter
Cells(j, 4).Value = i 'here is the thing.
'In the cell(row = j, column = 4 = D) put the value: i = the item of the list
'This take all the items of the list, inside the combobox.
Next i 'Next one please!
End Sub
Edit #1
Reading (aging) yous question, see that you want to write the list in a sheet that is not active... well here goes!
Private Sub CommandButton1_Click()
Dim i 'to store the item of the list
Dim j 'Just a counter
Dim sht As Worksheet 'the var for the sheet you want
Set sht = Sheets("S")
'the name of the sheet I want is "S", stored inside the var sht
j = 0 'Ini the counter
For Each i In Me.ListBox1.List 'Ini the for loop
j = j + 1 'Add one to the counter
sht.Cells(j, 4).Value = i 'here is the thing.
'In the cell(row = j, column = 4 = D)
'put the value: i = the item of the list
'This take all the items of the list, inside the combobox.
Next i 'Next one please!
End Sub
Edit#2
Now you can use it in a ListBox. And the change is pretty simple, just erase the ComboBox1 and write "ListBox1", it is functional with that two controls.
Edit #3
With this code you put everything inside a single cell
Private Sub CommandButton1_Click()
Dim i 'to store the item of the list
Dim j 'Just a counter
Dim sht As Worksheet 'the var for the sheet you want
Set sht = Sheets("S")
'the name of the sheet I want is "S", stored inside the var sht
j = 0 'Ini the counter
For Each i In Me.ListBox1.List 'Ini the for loop
j = j + 1 'Add one to the counter
sht.Cells(1, 4).Value = sht.Cells(1, 4).Value & Chr(10) & i
'here is the thing.
'In the cell(row = 1, column = 4 = D)
'put the value: i = the item of the list
'besides the others values.
'Everything inside a single cell
'This take all the items of the list, inside the combobox.
Next i 'Next one please!
End Sub
Tell me if you need some improvement.

Resources