Changing columns for Excel userform comboboxes - excel

Good morning,
I am in yet another rut and need some help. I have created a user form that allows a user to delete an entire rows worth of data on a second sheet (rawdata). Everything works fine using the code below, however the combo box ONLY shows the row number. I am in desperate need of changing the column so it will show the project names of the rows that need to be deleted.
Example:
Row: Project
1 Alpha
2 Beta
I would like the combo box to show Alfa and Beta and have the user be able to select the row they would like to delete based on that criteria.
The code below unhides and then hides the sheet that I want this deletion to occur on. This was done with purpose.
Private Sub ComboBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Dim lRw As Long
ActiveWorkbook.Sheets("RAWDATA").Visible = xlSheetVisible
'get the row number. add 1 because ListIndex starts at zero
lRw = Me.ComboBox1.ListIndex + 1
ActiveWorkbook.Sheets("RAWDATA").Select
Cells(lRw, 1).EntireRow.Delete
ActiveWorkbook.Sheets("RAWDATA").Visible = xlSheetHidden
End Sub
Private Sub CommandButton1_Click()
End Sub
Private Sub UserForm_Initialize()
'assumes data starts in A1 and has a header row
Me.ComboBox1.List = ActiveWorkbook.Sheets("RAWDATA").Cells(1, 1).CurrentRegion.Offset(1).Value
End Sub
Thanks for the help!

Change .Cells(1, 1) to .Cells(1, 2)
The Cells() method gives the code co-ordinates to a specific range using the row and the column number like so:
Cells(r, c)
so in your original code, the .Cells(1, 1) points to "A1" and then uses .CurrentRegion to get all cells within the region of A1.
By replacing the column number and using .Cells(1, 2) we tell it to look at "B1" instead - therefore shifting the column over to the right.
EDIT:
You could apply this logic to the Offset(r, c) function to shift the returned value over by 1 column - so:
.Cells(1, 1).CurrentRegion.Offset(1, 1)
This will more than likely be the culprit as the .Cells() method will point to a specific cell, but the .CurrentRegion() method will return the same result regardless unless we offset it.

Related

When I add a row in Excel to copy the previous row's formatting, can I also copy the form control checkboxes?

I have a table with checkboxes in certain columns (see sample table)-- they are linked to their cells and also move/size with the cells. I also added text box "headings" throughout the table so visually when you filter for checked boxes, you see under which heading the checked item is in (I know I could create a separate column for that, but it works if I add text to the cells underneath the heading that I keep checked when filtering).
I want to be able to add rows at the end of each section, or before the next heading, since the formatting changes slightly in each section. However, I also want to add the checkboxes, and my code currently doesn't do that. It's okay if they're not linked to the new cell-- I have another macro I can run to do that.
Here's what my code would look like in the sample table:
Sub Add_Row_Pepperoni()
Rows(7).Insert , xlFormatFromLeftOrAbove
End Sub
Sub Add_Row_Pineapple()
Rows(13).Insert , xlFormatFromLeftOrAbove
End Sub
And I would like to add "Next" to "Call" this code:
Sub Link_CheckBoxes()
Dim chk As CheckBox
Dim lCol As Long
lCol = 0 'number of columns to the right for link
For Each chk In ActiveSheet.CheckBoxes
With chk
.LinkedCell = _
.TopLeftCell.Offset(0, lCol).Address
End With
Next chk
End Sub
My other concern is the row I'm referencing (here rows 7 and 13) will change every time I add a row above it (I'll no longer be referencing the "header" row). Any tips?

How to get an output from a list box to populate some cells

I've created a userform with a couple of list boxes in. Listbox1 has all items in it, the user can select multiple values to then move into Listbox2. once they are in listbox2 I need them to populate some cells. With 1 list item per cell.
I'm having a pain trying to work out how to do it. So far all I've got is:
Private Sub CommandButton1_Click()
Dim tmpMsg As String
Dim t As Long
tmpMsg = "Selected categories:"
For t = 1 To ListBox2.ListCount
tmpMsg = tmpMsg & vbNewLine & ListBox2.List(t - 1)
Next
Worksheets("Specialist Prices").Activate
Range("a1").Select
ActiveCell.Value = tmpMsg
End Sub
This populates cell A1 with the entire set of list items. but I don't know how to put 1 value in a1 then move down and put the next in A2 and so on until all items are accounted for.
Any help would be appreciated.
Right now you are creating one string. It has linebreaks in it, but it´s still one text. If you are not using the tmpmsg for something else, you could use the for-loop to populate your sheet
For t = 1 To ListBox2.ListCount
Thisworkbook.sheets("Specialist Prices").Range("A" & t).value = ListBox2.List(t - 1)
Next
You can even do it faster by adding an array to the entire range. ListBox2.List is an array of values and you can paste that array into a range of cells:
ThisWorkbook.sheets("Specialist Prices").Cells(1,1).Resize(ListBox2.ListCount,1) = ListBox2.List
The Resize method here makes sure that the range contains the same amount of cells as there are elements in ListBox2. It resizes the range from 1 cell to a range of ListBox2.ListCount amount of rows and 1 column.

How to autopopulate excel column based on dropdown list selection from another column

I have a spreadsheet that has two buttons - To retrieve rows from a sql table using a macro and another one to update data changes back to the table from excel. I have also attached an image here for reference. The table columns are EmpID, EName, Grouping, CCNum,CCName, ResTypeNum, ResName and Status.
Now to update changes, I have drop down lists for CCName and ResName. I would like the ResTypeNum to change automatically whenever the value in ResName column from dropdown list changes. Using Vlookup doesn't seem to work as the formula gets wiped out every time I click on the Retrieve button to refresh data. Also, I have to drag down the formula which I don't want but instead the value in ResTypeNum should automatically update whenever the ResName column is changed. I would appreciate any new ideas to make this work.
Thank you,
Hema
Assumptions:
First value is in A4
ResName column is G
Sheet with data validation list and corresponding code in sheet "ResNameSheet"
In the tables sheet event module you place the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 7 And Target.Row > 3 Then
If Target.Value2 = "" Then
Target.Offset(0, -1).Value2 = ""
Exit Sub
End If
Dim rngDataValidation As Range
Dim rngRow As Range
Set rngDataValidation = ThisWorkbook.Sheets("ResNameSheet").UsedRange
For Each rngRow In rngDataValidation.Rows
If rngRow.Cells(1, 1).Value2 = Target.Value2 Then
Target.Offset(0, -1).Value2 = rngRow.Cells(1, 2).Value2
End If
Next
End If
End Sub
Explaining how the code works:
Fires on changes to the sheet
checks if changes are in column G (7) and that it occurs below the header row (3)
Checks that the change was not deleting from column G, if it is it clears all values on the corresponding column F
Loops through the Rows collection in the range with ResName list
Checks if values match
If it does it writes the corresponding code to the column to left of Target
Hope this helps.

Button Generates the columns from user input but not the cell lines?

I implemented a button that ask the user where to add a column, and the button takes the user input(A-Z) and generates the column until the end of the table NOT SPREADSHEET. The column ends based on how many rows there are in my table, meaning if there are 10 rows, after the user clicks the button an inputs where they want the column to be(They input a letter of the column A-Z), I should not see a column box on line 11 of the spreadsheet.
Now I've managed to do this my issue is below:
My issue is the cells the button generate does not include the lines or boxes around the cells so that you are aware that its an extension of the table?
here is what I mean: Picture of spreadsheet
notice the i column there are no lines around the cells?
Here is code, I think I am missing a copy function after the line
shift:=xlRight, but I don't know how to implement it?
I don't want to use macros because since the tables rows and column change due to the user's input I will have to constantly hard-code the range into the macro which i dont want.
Trust me I tried it an its annoying.
Private Sub CommandButton2_Click()
Dim x As Variant
Dim ColumnNum
x = InputBox("Enter a column that you want to add: ", "What column?")
If x = "" Then Exit Sub
ColumnNum = x
ThisWorkbook.Sheets("Sheet1").Columns(ColumnNum).Insert shift:=xlRight
ThisWorkbook.Sheets("Sheet1").Columns(ColumnNum).ClearContents
End Sub
you could try this:
Private Sub CommandButton2_Click()
Dim colIndex As Variant
colIndex = Application.InputBox("Enter a column that you want to add: ", "What column?", , , , , , 2) '<--| force a text
If colIndex = "" Then Exit Sub
With ThisWorkbook.Sheets("Sheet1").Columns(colIndex) '<--| reference column you want to insert
.Insert shift:=xlRight '<--| insert a new column , then the referenced one shifts one column to the right of the inserted one
.Offset(, -2).Copy '<--| copy the column two columns to the left of the referenced one (i.e. one column left of the new one)
.Offset(, -1).PasteSpecial xlPasteFormats '<--| paste formats to the new column
Application.CutCopyMode = False
End With
End Sub

Data validation list, combo box, or active X combo box in Excel 2010?

Started with a data validation list and I like that it is in the cell where I want the data to appear. Tried combo box and active X combo box and don't like that they do not reside in the cell. This is very different than Access. This is what I am trying to accomplish:
My named range (Employee) is A4:C100, 3 columns, with headings Title, MI, and LN on a sheet named "Emp".
My form location is C6. I wanted to be able to show 3 columns and end up with data from the three columns. For example, Officer J. Doe.
Currently I am using data validation list entering data into one column as Doe, J., Officer and it works. The list can be long and I will need it to be in alphabetical order.
Is this the best way or am I confused with combo box and active X combo box?
The only way to show a combination of all 3 columns in a dropdown list is to concatenate the data in a 4th column e.g. use the following formula in Cell D4
=A4&" "&B4&" "&C4
...then you can name the range D4:D100. You may wish to hide this column for presentational reasons
Actually, you will probably want to avoid naming the whole range as the bottom cells may be blank/make scrolling more awkward than strictly necessary. I would recommend dynamic ranges
The next extension exercise might be to develop your formula to allow for e.g. a missing middlename e.g.
=A4&" "&IF(B4<>"",B4&" ","")&C4
The above assumes you can sort the data manually. If the data is not being sorted manually, you will need to use VBA e.g. ensure Column D gets completed and the named range created each time a user moves off Sheet("Emp"). You can embed the following code in the Emp sheet...
Private Sub Worksheet_Deactivate
For n = 4 to 100
If Cells(n, 1) <> "" Then
Cells(n, 4) = Cells(n, 1) & " " & Cells(n, 2) & " " & Cells(n, 3)
End If
Next n
Range(Cells(4,4),Cells(100,4)).Sort Key1:=Cells(4,4), Order1:=xlAscending, Header:=xlNo
LastRow = 4
Do Until Cells(LastRow + 1, 4) = ""
LastRow = LastRow + 1
Loop
ActiveWorkbook.Names.Add Name:="Employee", RefersTo:=Range(Cells(4,4),Cells(LastRow,4))
End Sub
The expressions for sorting/adding range names can be found by recording macros and eliminating code as in this expert Excel support video. Your data validation would refer to 'Employee' which is the range name created in the 4th column
There are a number of assumptions made above such as the idea that all employees have data in the first column and you would need to add logical tests if you do not always have data in all three columns
It may also be that you would prefer to create the Employee range when a user clicks in cell C6 of your form, as this may be more robust. My assumption in using Worksheet_Deactivate is that 'Employee' may be used elsewhere in your spreadsheet
Something like this. Put this code in your worksheet where the comboBox is
Private Sub Worksheet_Change(ByVal Target As Range)
Dim topY As Integer, leftX As Integer
topY = ComboBox1.top
leftX = ComboBox1.left
Dim c As Range
Set c = Cells(5, 5)
c.Left = topY
c.Top = leftX
c.Width = ComboBox1.Width
c.Height = ComboBox1.Height
End Sub
It should keep it locked in place if you move things around. Or you could try it in your Private Sub Worksheet_SelectionChange(ByVal Target As Range) event.

Resources