Userform to populate worksheet - excel

I'm still very new to using VBA, so I apologize if I don't know all of the preferred terms.
I am attempting to write a userform to populate a spreadsheet allowing me to track employees PTO used. This spreadsheet is the X-axis (row 1) being the date and the Y-axis (column A) being the employee name.
The userform I've created has 5 pieces of criteria:
1) Employee Name (ComboBox1; this is a drop down of multiple rows)
2) Date of PTO (ComboBox2; this is supposed to be a drop down of multiple columns)
3) Duration of PTO (OptionButton1 is 1 Day, OptionButton2 is 0.5 Day)
4) Enter Data (CommandButton1)
5) Cancel (CommandButton2)
I've completed criterion 1 by selecting and labeling the menu on the spreadsheet.
The rest is what's kicking me.
I cannot seem to get the dates (criterion 2), while in row format, to show up in the ComboBox2 drop down. If I transpose these items into a single column, I have been able to label the group and create the drop down menu. This is problematic as I will not be able to form a grid to populate.
My OptionButton1 and OptionButton2 items are intent to be the input values (1 and 0.5). At this time, I've been unable to give them values, simply names. This input is secondary to the major issue where I cannot get the grid format to work (paragraph above this).
The tertiary problem is the combination of criterion 4 and 5. My script is failing to execute CommandButton1, though I believe it's due to my extremely basic code:
Private Sub CommandButton1_Click()
cmdOK
End Sub
CommandButton2 appears to work using this code:
Private Sub CommandButton2_Click()
cmdCancel
End Sub
My end all be all question, having described my issues, would be "Is my end goal possible?" I only intend to use Excel for this, as many people already have access to it. If this is possible, then I would ask for either help identifying my error points and correcting, or a link to a coding manual where I can attempt to learn more about the functions (this is more of a long-term situation, which doesn't quite help the issue, but I would feel okay with).
Thank you in advance for responses.
Edit:
# Seth
I've made it as far as ComboBox2 (the dates) selection. I cannot get the loop, suggested below, to access the values (1 row, 365 columns).
I tried modifying the code from Seth, but I really don't know anything about loops; I feel I most likely did not fill out a section appropriately (I'm looking at .Value <> ""):
Private Sub ComboBox2_Change()
Dim i As Long
i = 1
Do While ThisWorkbook.ActiveSheet("Breakdown").Cells("A1:NC1", i).Value <> ""
Me.ComboBox1.AddItem (ThisWorkbook.ActiveSheet("Breakdown").Cells("A1:NC1", i).Value)
i = i + 1
Loop
End Sub
Using this code, I get the error "Run-time error '438': Object doesn't support this property or method"
I'm trying to find a general guide to understanding writing a loop, though I find no reference to some of the above statements, so I'm not positive how to correct my problem. I believe it might also have something to do with the properties of the box. I can enter "Dates" (my generic term for that range as defined by highlighting and labeling as such) under RowSource, though that is not looping the rows.
# Alex D
I am also attempting the path of the second post I received; i get a runtime error when I try to use:
Private Sub UserForm_Initialize()
For i = 2 To Sheets("Breakdown").UsedRange.Columns.Count
comboDate.AddItem (Cells(1, i))
comboDate.List(comboDate.ListCount - 1, 1) = i
Next
End Sub
Possibly moving where that data is defined would make this work? In general, I have a button in the sheet (aka one selects a cell and the userform pops up), so possibly the initialize isn't necessary?
Cyril 20140127 (1700 UTC)

Ok, let's go in reverse order. To your last question, "Is my end goal possible?", the answer is "sure." I don't quite follow your reasoning, but if you prefer to use Excel, so be it. I do think, though, that this going to be a painful way of recording PTO. What if, for example, I take a week off? Do I have to fill out this form once for each day?
To continue moving in reverse, your buttons need to do something. It's unclear from what you've posted if cmdCancel and cmdOK are subs that you've defined elsewhere so let's pretend they aren't. In your Cancel button you need to do one basic thing, close the form. That should be as simple as this, Unload Me.
Your OK button is the crucial piece of your macro. It's where you stitch together the values the user has entered. It's also where you do something with your option buttons. You don't actually assign values to the option buttons, you check their Value properties. So, when you users click OK the code that runs will have something in it like this:
If OptionButton1.Value = True Then
'Put 1 in the cell.
Else
'Put .5 in the cell.
End if
Note that there's no need to explicitly check OptionButton2, since you only have two choices.
Finally, the dates. It sounds like the dates are already in your spreadsheet, in some particular row. What you need to do here is loop through the cells in that row and pull the values into the list of the combo box. This should get you started. Put it the UserForm_Activate form event:
Dim i As Long
i = 1
Do While ThisWorkbook.ActiveSheet.Cells(DateRow, i).Value <> ""
Me.ComboBox1.AddItem (ThisWorkbook.ActiveSheet.Cells(DateRow, i).Value)
i = i + 1
Loop
Now we return to the OK button. You need to get the selection that was made in the date combo box. To do that you need to read the ListIndex property of the combo box and add one to it. (Adding 1 accounts for the fact that the list in the combo box starts 0, not 1.) The number that is the returned will be the column in which you insert your data.
The complete code for the OK button would be something like:
Dim Col As Long
Dim Row As Long
Dim PTOValue As Long
Col = DateComboBox.ListIndex + 1
Row = EmployeeNameComboBox.ListIndex + 1
If FullDayComboBox.Value = True Then
PTOValue = 1
Else
PTOValue = .5
End if
ThisWorkbook.ActiveSheet.Cells(DateRow, i).Value = PTOValue
Hopefully this will get you started.

Fills your criterion, and should be understandable. Assumes names start in cell(2,1) and Dates in cell(1,2). You might have to change some of the names of the elements depending on what you have. But I fully built something like you described and it works perfectly.
It does need some data validation to prevent errors, but you should be able to handle that.
'Ok button which sets the values
Private Sub CommandButton1_Click()
Columns("A:A").Select
If OptionButton1.Value = True Then
Cells(Get_Name_Row(comboName.Text), Get_Date_Column(comboDate.Text)).Value = 1
Else
Cells(Get_Name_Row(comboName.Text), Get_Date_Column(comboDate.Text)).Value = 0.5
End If
End Sub
'Cancel Button
Private Sub CommandButton2_Click()
Unload Me
End Sub
'This loads the dates into your comboBox, make sure to update its name
'I assume you use RowSource for your names, so those should be fine
Private Sub UserForm_Initialize()
For i = 2 To Sheets("Sheet1").UsedRange.Columns.Count
comboDate.AddItem (Cells(1, i))
comboDate.List(comboDate.ListCount - 1, 1) = i
Next
End Sub
'Gets what row the name is from
Public Function Get_Name_Row(SearchString As String) As Integer
Dim Rng As Range
If Trim(SearchString) <> "" Then
With Sheets("Sheet1").Range("A:A")
Set Rng = .Find(What:=SearchString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Get_Name_Row = CInt(Rng.Row)
End If
End With
End If
End Function
'Gets what column the date is from
Public Function Get_Date_Column(SearchString As String) As Integer
Dim Rng As Range
If Trim(SearchString) <> "" Then
With Sheets("Sheet1").Range("A1").EntireRow
Set Rng = .Find(What:=SearchString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Get_Date_Column = (Rng.Column)
End If
End With
End If
End Function

Related

Non-Standard "Conditional" configuration of ComBox1

My problem is how to populate the cmbSelProp ComboBox with propIDs from a workbook scoped Named Range called PropLocs. The columns of interest Column "A" which contains the list of propIDs and Column "K" which contains the ActiveStatus of each propID. I also have Named Ranges for both columns of interest, propIDs and actStatus respectively. The actStatus, Column "K", portion of the range are set to True/False when the properties are added and subsequently initialized and annual worksheets are automatically generated.
I only want cmbRptPrpID populated with propIDs having an actStatus = True.
I have spent many hours over the past few weeks going blind doing Web Searches, looking at links, and trying suggestions from the various links without success. I,m as "Lost as a blind man in a snow storm!"
There are broader issues associated with the problem I am dealing with and understanding how to solve, and understand, the issue at hand will help me in the future development of my application.
UPDATE
the 2 mentioned additional ranges are in columns "A" and "K"
Update 2
Business Logic
The application I am developing utilizes a multipage object and there are pairs of dynamic comboboxes, cmbSelProp and cmbYears for example, used to select the active worksheet and enter Monthly expenses, view/generate Reports, etc. cbmSelPropselects the property ID, and the cbmSplProp_Change() event configures cmbYears list values based on the variable wsStartYr in column "K" and wbCurYear which is the Current Calendar Year. the annual worksheets have a Worksheet TabName of propId_Year and are selected using a variable wsA = pID & "_" & wsYr. I do not want propIDs with an Inactive status to appear as a part of the cmbSelProp list values.
This is a link to My First Question here on StakOverflow which is related to this question.
I really need some help figuring this out!
Thanks in advance for your assistance.
here is the code I have been trying to work with.
selectedRow = cmbSelProp.ListIndex + 3
For Each cPart In wsCntrl.Range(Range("propIDs"), Range("A" & Rows.Count).End(xlUp))
pAct = wsCntrl.Cells(selectedRow, "K").Value
With Me.cmbSelProp
If pAct = "True" And cPart.Value <> "" Then cmbSelProp.AddItem cPart.Value
End With
Next cPart
There are a number of issues in your code. Rather than breaking down all the errors/issues, I'll show you how I would do it.
From your previous Q, I take it that your Combo Box is on a Userform.
I've created a Userform with a combo box and a button to load it. You can change how you call the load function to suit your needs.
The UserForm code
Option Explicit
Private Sub btnTest_Click()
Load_cmbSelProp
End Sub
Private Sub Load_cmbSelProp()
Dim propIDs As Range
Dim actStatus As Range
Dim rw As Long
Set propIDs = ThisWorkbook.Names("propIDs").RefersToRange
Set actStatus = ThisWorkbook.Names("actStatus").RefersToRange
Me.cmbSelProp.Clear
For rw = 1 To propIDs.Count
If propIDs.Cells(rw, 1).Value2 <> vbNullString Then
If actStatus.Cells(rw, 1).Value2 = True Then
Me.cmbSelProp.AddItem propIDs.Cells(rw, 1).Value2
End If
End If
Next
End Sub
The Named ranges
The result

Create dependent drop lists (using data validation or combo box) with auto refresh

I want to create many dependent drop list (more than 100) that auto refresh when the source list changes.
I am able to auto update the list using data validation and by changing the source list using named ranges but the selected item doesn't change unless I re-select the data validation list.
lets take as a simplified example the following:
category_List:
colors = {black, red, green}
languages = {english, french, spanish}
So if i select colors, i want to display the colors list and if I select the languages then I want to select the languages list. If red was selected then when i change to languages category, I want the french to be automatically selected and so on.
I am aware of two solutions:
1) https://www.youtube.com/watch?v=wWasYHG1lmM&list=PLmHVyfmcRKywYhC1Q9eZqR7D-_cdiwl6y&index=12
Uses VBA to do that, but since I have more than 100 list and the dependent list are random then I have to manually change each list when a specific source list changed. I dont think this the best idea.
2)https://www.youtube.com/watch?v=aSPtWo3IiOM&list=PLmHVyfmcRKywYhC1Q9eZqR7D-_cdiwl6y&index=11
A better approach as this will automatically change the selection when the category changes and it also give an additional feature which is the linked cell that gives a bi-directional connection between the cell and the combo box.
But my issue is that linked cell returns a 1-based index and I want that to be 0-based index. So if I select the first element, I want the linked cell to display 0 not 1 and vice versa...
Is there a way to achieve what I want easily ? either using one of the proposed approach or using another one ?
thanks
If I understand your question correct, you want something like this.
Create 2 comboboxes on your sheet.
In VBA make the following code:
Sub PopulateComboBox_Category()
Dim N As Long, i As Long
With Blad1
N = .Cells(1, Columns.Count).End(xlToLeft).Column
End With
With Blad1.ComboBox2
.Clear
For i = 1 To N
.AddItem Blad1.Cells(1, i).Value
Next i
End With
End Sub
Sub PopulateCombobox()
Dim Targetcell As Range
Dim strCategory As String
strCategory = Blad1.ComboBox2.Value
Set Targetcell = Range("1:1").Find(What:=strCategory)
Dim col As Long
col = Targetcell.Column
Dim N As Long, i As Long
With Blad1
N = .Cells(Rows.Count, col).End(xlUp).Row
End With
With Blad1.ComboBox1
.Clear
For i = 2 To N
.AddItem Blad1.Cells(i, col).Value
Next i
End With
End Sub
Make a change event on the sheet with the following code.
Private Sub ComboBox2_Change()
Call PopulateCombobox
End Sub

Excel - how to memorize click-state of a button workbook-wide? (e.g. to show-hide data or join with another button's state)

(TLDR: question is until "use-case:")
I am trying to erase values in an excel column when a button is pressed a second time.
At this stage, I have a button with following code that displays values from another sheet if pressed. The data is just displayed in the current sheet, it will never be more than a number of columns, say max 10, and they will be copied in / removed depending on button state.
(implemented as ActiveX button through developer tools):
Private Sub Button_Click()
Worksheets("myworksheet.xlsx").Columns("E").Copy Destination:=Sheets(1).Columns("S")
End Sub
I would like to store certain values globally for the duration of the session so if another button is pressed, it can get the state of this button too (in order to join data referred to by the two buttons).
What would be the best way to store these values and retrieve them?
PS this is my first foray into Excel vba. Main goal is minimum overhead but still extensible to more logic. So any ugly but quick solution that works up to say 20 params, is also fine with me... "time to market" is critical.
thank you very much for your time and help.
use-case:
Show all involved tables or objects in a data loading process, from input file to reporting domain - but only show those objects for which the relevant buttons are pressed. E.g. show all target tables in Domain "A", or show all reports using source files in soure feed "X".
button 1 has label "Domain A". If pressed, it will get all Jobs that are listed in the "Domain A" Column in another sheet and display them.
Button 2 has label "CORE Database". If pressed by itself, it will show all values from the "tables" column in the Database Sheet that have value "CORE" in another column.
If both buttons are pressed, I want to display all jobs in Domain A with all tables in "CORE Database" that they have as targets.
Then, if button "CORE Database" is pressed again, ie "toggled off", the display should go back to only showing all Jobs for Domain A.
Now if a third button is pressed, labeled "VIEW Layer", the combination of all views for all jobs in Domain A should show up.
Combining all three buttons should then show the combinaiton of all three.
The logic that is behind this, could be implemented in many was I guess, and I will see how far I get. The starting point is to have a decent location for storing these states, there may be up to 30 buttons if things get really wild.
Each button essentially adds its own column ("Dimension"), and whatever is displayed, will be a cross-section of all of these. So it is important, to know at any time, what buttons are pressed.
Update 2:
some example in data (warning, this goes beyond the original question):
Jobs sheet holds jobs and their tables.
Views sheet holds views and their source tables.
if only the "Jobs" button is selected, display:
SOURCE DATA: Jobs, deduplicated
if only the "View" button is pressed, display all the views in the database, deduplicated.
For example:
if only the "CORE" button is selected, display all the tables in the core database, for example:
JOINED DATA: tables, taken from the Jobs sheet and the view sheet, deduplicated
(edit: this is inconsistent, as the tables X and Y show up out of nowhere, they could be left out or more jobs showing)
if the Jobs and Core button is pressed, show (this is directly from the Jobs sheet):
SOURCE DATA: Jobs and their target tables
If the tables and views button is pressed:
(in this example case, View B is not delivered by any job)
SOURCE DATA: Views and their source tables
(so ViewA uses two tables as source)
if the "Job" and "View" buttons are pressed:
JOINED DATA: Views and relevant jobs, joined through their matching tables
and finally if all three buttons are pressed, essentially more columns are shown and more rows are shown, since there is less deduplication:
JOINED DATA: Views and relevant jobs, joined through their matching tables, showing all
(despite the confusing name "B", ViewB is not loaded by jobB. Should have picked different name, in retrospect)
This solution is based on a new worksheet with 3 activeX toggle buttons (all with default names).
I've first bound a cell to each toggle button - A1 to ToggleButton1, B1 to ToggleButton2 and C1 to ToggleButton3. This returns either TRUE or FALSE to the cell based on the state of the ToggleButton.
ToggleButton control MS documentation
For visuals, here is the source data:
Note: As it's not that easy to see whcih ones are clicked in at a glance, you can change the back colour of the buttons in the ToggleButton_Click event.
Like so:
With Sheet1.ToggleButton1
If .Value = True Then
.BackColor = &HFF00&
ElseIf .Value = False Then
.BackColor = &H8000000F
End If
End With
End Sub
Private Sub ToggleButton2_Click()
With Sheet1.ToggleButton2
If .Value = True Then
.BackColor = &HFF00&
ElseIf .Value = False Then
.BackColor = &H8000000F
End If
End With
End Sub
Private Sub ToggleButton3_Click()
With Sheet1.ToggleButton3
If .Value = True Then
.BackColor = &HFF00&
ElseIf .Value = False Then
.BackColor = &H8000000F
End If
End With
End Sub
I first define the last column dynamically based on the first row of values.
Info about finding the last row/column
Note: I've included 2 statements for SourceLastCol - use one or the other depending on how your sheet is set up - If you leave it as is, it will use the value from the 2nd statement.
Using the last column found, I then loop each cell in the range for row 1 from column A to the last column.
If the value is True it then spits that columns values out into another worksheet (in this case, Sheet2) to TempDestinationRange using TempArray. (See http://www.cpearson.com/Excel/ArraysAndRanges.aspx for more info about this method).
It would probably be best to have a Submit command button to trigger the sub rather than run it each time a toggle button is clicked (as if you have 30 and someone changes them all that's a lot of redundant worksheet changes).
Sheet2 output :
Sub CheckToggleAndJoinData()
Dim SourceLastCol As Long
Dim SourceLastRow As Long
Dim SourceRange As Range
Dim CellToCheck As Range
Dim TrueRange As Range
Dim DestinationRange As Range
Dim DestinationLastRow As Long
Dim DestinationLastCol As Long
Dim TempArray As Variant
With Sheet1
SourceLastRow = .Cells(Rows.Count, "S").End(xlUp).Row
.Range("S1:S" & SourceLastRow).ClearContents
SourceLastRow = 0
SourceLastCol = Sheet1.Cells(1, Columns.Count).End(xlToLeft).Column 'Use this one if there is no data to the right of your source columns.
SourceLastCol = Sheet1.Cells(1, 1).End(xlToRight).Column 'Use this if there is data to the right of your source columns (note this will not work if there are blank gaps in your source columns)
Set SourceRange = .Range(.Cells(1, 1), .Cells(1, SourceLastCol))
End With
Dim TrueColumnArray As Variant
Dim ColumnToCheck As Long
Dim ColumnCounter As Long
ColumnCounter = 0
For ColumnToCheck = 1 To SourceLastCol
With Sheet1
If .Cells(1, ColumnToCheck).Value = True Then
ColumnCounter = ColumnCounter + 1
SourceLastRow = .Cells(Rows.Count, ColumnToCheck).End(xlUp).Row
Set TrueRange = .Range(.Cells(2, ColumnToCheck), .Cells(SourceLastRow, ColumnToCheck))
DestinationLastCol = Sheet2.Cells(1, Columns.Count).End(xlToLeft).Column
If ColumnCounter = 1 Then
Set DestinationRange = Sheet2.Cells(1, DestinationLastCol)
Else
Set DestinationRange = Sheet2.Cells(1, DestinationLastCol + 1)
End If
TempArray = TrueRange
DestinationRange.Resize(UBound(TempArray, 1), 1).Value = TempArray
End If
End With
Next ColumnToCheck
End Sub
To de-duplicate your data (as mentioned in some comments/edits/chat) you may want to look into using a Dictionary object as this will store each input value as a Key - ignoring subsequent occurrences of this value.
-edit: I wrote this BEFORE Samuel's answer, so that is obviously making this irrelevant :)
for now I will just go with following solution, it works for me, beauty is not so important right now
-update: I am now going with global variables, of course my programmermind tells me this is risky and dangerous, but I just need results for now, and they are booleans for states, only. Any suggestions are still very welcome.
Here is some code that I have now:
Public CORE_Pressed As Boolean
Sub clearCol(colLabel As String)
Columns(colLabel).ClearFormats
Columns(colLabel).ClearComments
Columns(colLabel).ClearHyperlinks
Columns(colLabel).Clear
End Sub
Private Sub Workbook_Open()
SLJM_Pressed = False
End Sub
Private Sub CORE_Button_Click()
CORE_Pressed = Not CORE_Pressed
If CORE_Pressed = True Then
Worksheets("CORE.xlsx").Columns("E").Copy Destination:=Sheets(1).Columns("S")
Else
clearCol ("S")
End If
End Sub
I will probably move the button handling into a central function, but this is just to show the current approach.
Also many thanks for the comments posted by Samuel Everson, they gave a very interesting alternative for when things need to be more "professional". global variables are ugly I know.

Excel Randomly crash after executing Macro

I am tearing my hair out on this one.
I am trying to add the value from a userform textbox to a table.
However Excel is constantly crashing on me as soon as it runs the code below.
The error message i get is
runtime error -2147417848 "Method 'Value'of object 'Range' failed
then excel crashes
I have tried Option explicit to check i wasnt missing a variable or it was declared incorrectly, i have tried deleting the table and starting again, i have started a new workbook, i have change the table name, i have tried 4/5 different methods of adding the data to the table (Simple range offset, databodyrange(X,1), resizing the table etc). All crash when adding the value (which by the way is just text like mike/harry etc)
The workbook, has about 10 forms and they all work perfectly (they add data to tables etc), it is just this one causing issues
If i manually add data to the table it auto extends and have no issues
any help is appreciated.
Sub Enterprise_Update()
Dim lst As ListObject
Set lst = Sheets("Data Labels").ListObjects("Enterprises")
For Each ctrl In Enterprise_Setup.Controls
If ctrl.Name Like "Enterprise Name Value 1*" Then
z = z + 1
End If
Next ctrl
With lst.Sort
.SortFields.Clear
.Apply
End With
With lst
LstRw = .ListRows.Count
End With
Select Case LstRw
Case Is = 1
lst.DataBodyRange(LstRw, 1).Offset(1, 0).Value = Enterprise_Setup.Controls("Enterprise Name Value 1" & x)
Case Else
For x = 1 To z
sLookFor = CStr(Enterprise_Setup.Controls("Enterprise Name Value 1" & x))
Set oLookin = lst.DataBodyRange
Set oFound = oLookin.Find(what:=sLookFor, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=True)
If Not oFound Is Nothing Then
GoTo err:
Else
With lst
LstRw = .ListRows.Count
End With
End If
r = Enterprise_Setup.Controls("Enterprise Name Value 1" & x).Value
Sheets("Data Labels").Select
Range(lst.Range.Cells(1).Address).End(xlDown).Offset(1, 0).Select
ActiveCell.Value = r
'lst.DataBodyRange(X).Value = r
err:
Next
End Select
With lst.Sort
.SortFields.Clear
.SortFields.Add Key:=Range("Enterprises[Enterprises]"), Order:=xlAscending
.Header = xlYes
.Apply
End With
End Sub
I'm looking at this portion of your code and have some comments on it.
If Not oFound Is Nothing Then
GoTo err
Else
LstRw = Lst.ListRows.Count
End If
r = Enterprise_Setup.Controls("Enterprise Name Value 1" & x).Value
Sheets("Data Labels").Select
Range(Lst.Range.Cells(1).Address).End(xlDown).Offset(1, 0).Select
ActiveCell.Value = r
For one, GoTo err? Err is VBA's error object. VBA is very good at avoiding errors from intrusions on its naming prerogative but I still think its asking for trouble. Note that the final colon is required to identify the label but not the destination statement.
Using labels to jump back and forth in the code isn't good practice. Nor is it needed in this case. A simple If Not oFound Is Nothing Then should do the job if you extend the End If to the point where you have the label. Anyway, what's the point of LstRw = Lst.ListRows.Count? You took that measure before the Select Case statement. Has it changed?
But most of all, I question why you would jump if you found what you were looking for and process when you didn't. This is the best candidate for the error you see.
Selecting another sheet is not good practice and not required, either. You can read from and write to the sheet without selecting it. If you are selecting the sheet from a user form Excel might consider this cause for divorce. Of course, selecting a cell is equally unnecessary.
Range(Lst.Range.Cells(1).Address).End(xlDown).Offset(1, 0) probably works, although I think it's adventurous. But selecting that cell may be problematic when done from within a user form. The form sort of claims right of first attention. I doubt that you can activate that cell from where you are.
You can write to it, however. Sheets("Data Labels").Cells(54, "A").Value = r would be a great success, I feel confident. The contortions you undertake to describe the cell's coordinates aren't necessary. The column seems to be Lst.Range.Column and the row would be Lst.Range.Row + LstRw or perhaps Lst.DataBodyRange.Row + LstRw.
However, there might be additional problems resulting from the location of the cell in a table or just under a table where adding a row might create conflict with data existing there. If the table is required to expand as a result of writing to that cell Excel would normally just over-write whatever might exist but it's a point worth considering if all other options have been exhausted.
I hope this analysis will help you find and correct the error.
I solved the issue by a less than pretty way. I managed to extend the table, and code around the blank rows, ie count none blanks, dynamic named ranges etc

How to plot a chart with known column index in vba

I am trying to create a simple userform to plot graphs of selected columns.
What I did so far is shown in the code below:
Public Sub UserForm_Initialize()
Dim Axis As Variant
Dim Axis1 As Variant
Axis = Rows(1).Value
' here I'm filling the Comboboxes with all the names in the 1st row
ComboBox1.Column = Axis
ComboBox2.Column = Axis
End Sub
Public Sub Plot_Click()
With Range("A1:ZZ1")
'Here I'm searching for the column index of the selected value in the first Combobox
Set rFind1 = .Find(What:=ComboBox1.Value, LookAt:=xlWhole, _
MatchCase:=False, SearchFormat:=False)
End With
Spalte1 = rFind1.Column
With Range("A1:ZZ1")
'Here I'm searching for the column index of the selected value in the second Combobox
Set rFind2 = .Find(What:=ComboBox2.Value, LookAt:=xlWhole, _
MatchCase:=False, SearchFormat:=False)
End With
Spalte2 = rFind2.Column
'somewhere here, I would like to plot a graph with the selected
'column indexes (Spalte1 and Spalte2)
End Sub
Private Sub Schliessen_Click()
'here I'm closing the userform
Unload Me
End Sub
The graph should look like this:
And in the future, I will also add some more Comboboxes in order to select more axis to plot
I appreciate every single answer/help and suggestion
The way, you are initializing the ComboBox will add many blank items which will become cumbersome while selecting required value. I will suggest to add only required columns instead.
Searching the selected column index again and again is also meaningless. You can use .ListIndex property to get 0 based index value. Hence the actual column index will be ComboBox1.ListIndex + 1 in case.
As you may require to add more ComboBox in future, I would rather suggest to use two ListBoxes, first with all column names and second will get updated with require columns to be used as series using Add, Remove buttons as following screenshot:

Resources