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

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

Related

find blank cells in columns and replace them with 0, repeat for next row if next row has data

I am using excel userform to input the data. I want for Columns C2:F2, if the user has not inputted any number in it, excel should convert these blanks into 0. And I want it to repeat for the next row when the data for next row is inputted. I tried some simple coding but it didn't work.
Public Sub BlankCells()
Dim rng As Range
rng = Range("C2:C1000", "D2:D1000", "E2:E1000", "F2:F1000")
For Each cell In rng
If cell = "" Then cell.Value = "0"
Next cell
Find
End Sub
It works if use coding for single row only i.e. "C2:F2", but i want it repeat for the next rows as well when the next row gets the data.
When you create a variable for sheet or range, you need to use the Set keyword like this:
Set rng = Range("C2:F1000")
If you'd like to refer to multiple ranges, you can add all the ranges as one comma separated string

Copy unique values in Excel VBA

I have written VBA code that copies a filtered table from one spreadsheet to another. This is the code:
Option Explicit
Public Sub LeadingRetailers()
Dim rngRows As Range
Set rngRows = Worksheets("StoreDatabase").Range("B5:N584")
With rngRows
.SpecialCells(xlCellTypeVisible).Copy _
Destination:=Worksheets("LeadingRetailersAUX").Range("B2")
End With
Sheets("Leading Retailers").Activate
End Sub
The filter is applied before the code is ran and then the code selects the visible cells and copies them so as to get only those rows that passed the filter.
In the filtered table to be copied I have, in column L of the range, a certain set of names, some of which are repeated in several rows.
I would like to add to the code so that it only copies one row per name in column L. In other words, I would like the code to copy only the first row for each of the names that appears in Column L of the filtered table.
Pehaps something like this can help you. Code will loop through your rows (5 to 584). First it checks if row is hidden. If not, will check if the value in column "L" is already in the Dictionary. If it is not, it will do two things: copy the row to Destination Sheet, and add the value to the Dictionary.
Option Explicit
Public Sub LeadingRetailers()
Dim d As Object
Dim i As Long
Dim k As Long
Set d = CreateObject("scripting.dictionary")
i = 2 'first row of pasting (in "LeadingRetailersAUX")
For k = 5 To 584
If Not (Worksheets("StoreDatabase").Rows(k).RowHeight = 0) Then 'if not hidden
If Not d.Exists(Worksheets("Hoja1").Cells(k, 12).Value) Then 'if not in Dictionary
d.Add Worksheets("StoreDatabase").Cells(k, 12).Value, i 'Add it
Worksheets("LeadingRetailersAUX").Cells(i, 2).EntireRow.Value = Worksheets("StoreDatabase").Cells(k, 1).EntireRow.Value
i = i + 1
End If
End If
Next
End Sub
You could apply another filter to the table to only show the first occurrence of each set of names and then run your macro as usual. See this answer:
https://superuser.com/a/634284

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.

Add Conditons to Unhide column in a sheet with Mulitple Criteria

A little Help again please.
Codes below work for hiding columns that do not match B5.
Now my problem is, I want to unhide column that matches values
from B6 and B7 at the same time.
Reference Values from Command Sheet Column B Row 5,6,7.
Let B5 is MARCH
Let B6 is JANUARYsample picture
Let B7 is FEBRUARY
Sheet Name (GRA_NewGen CI) Note that All Data's per row/column are here.
Range from Sheet Name to Match B5,B6,B7 is Column C Row 4 up to End of Column in row with Values.
Below is the 'Code
'Sub GRA_NewGen_CI()
Dim cell As Range
Application.ScreenUpdating = False
With Sheets("GRA_New Gen CI")
For Each cell In .Range("C4", .Range("XFD4").End(xlToLeft))
cell.EntireColumn.Hidden = cell.Value <> Sheets("Command").Range("B5") And Not IsEmpty(cell)
Next cell
End With
Application.ScreenUpdating = True
'End Sub
If all you want is to hide all rows marked "JANUARY", "FEBRUARY" etc. you will have more flexibility and faster action by using Excel's Filter functionality. Learn here about Filters.
That gave me quite a ride. All those hidden columns are tricky. But now it's your turn. Please follow the instructions.
On your 'Command' sheet, find a blank column and enter "Show All" in one of the cells and this function in the cell below that:
="Show "& B5
I prefer you to have all the 12 months in B5:B16, but if you have only Jan to Mar or prefer to change the content on the fly that is OK as well. Copy the formula down for as long as you have relevant data (month names or column captions) in column B. Give the range I just described a name. I gave it the name "DropdownList". Make sure the named range has a 'Scope' of "Workbook" (meaning, it is visible from all parts of the workbook).
Place a command button on the GRA_New sheet in position A4. Perhaps you already have a button elsewhere. In that case I will ask you to play along and make another one for now. Later you can move this button to any other location, including another sheet, but not in a column to be possibly hidden. This command button will be a Validation drop-down. Enter
"Allow" = List and
"Source" =DropdownList (including the = mark.
You should now have a validation dropdown showing "Show All" in first position, "Show January" in second, and more "Show ..." depending upon the size of the named range DropdownList. Make sure that there is a single space between in "Show January" and "Show all", not more and not less, and every line consisting of 2 words, the second of which is relevant.
Now add the following procedure to the code sheet of the "GR_New ..." sheet.
Private Sub Worksheet_Change(ByVal Target As Range)
'17 Mar 2017
If Target.Address = Range("A4").Address Then
SetDisplay_GRA_NewGen Split(Target.Value)(1)
End If
End Sub
In this procedure, please change the reference to "A4" to the cell where you have the validation dropdown.
The next procedure goes into a normal code module. By default its name would be "Module1", but you can give it any name you like.
Sub SetDisplay_GRA_NewGen(ByVal Cmd As String)
' 17 Mar 2017
Dim Spike As String
Dim CountHidden As Integer
Dim FirstColumn As Long, LastColumn As Long
Dim CapRow As Long, Cap As String
Dim C As Long
CapRow = 4
FirstColumn = 3 ' = column C
With Worksheets("GRA_New_Gen_CI")
LastColumn = .UsedRange.Columns.Count
If StrComp(Cmd, "all", vbTextCompare) Then
With Range("DropdownList")
For C = 2 To .Rows.Count
Cap = Split(.Cells(C).Value)(1)
Spike = Spike & "|" & Cap
Next C
End With
For C = FirstColumn To LastColumn ' count hidden columns
Cap = .Cells(CapRow, C).Value
If .Columns(C).Hidden Then
If .Columns(C).Hidden Or InStr(1, Spike, Cap, vbTextCompare) = 0 Then
' if Cap can't be selected it is counted as not hidden
CountHidden = CountHidden + 1
End If
End If
Next C
Application.ScreenUpdating = False
If CountHidden = 0 Then
' hide all except the specified column
.Range(.Columns(FirstColumn), .Columns(LastColumn)).Hidden = True
End If
For C = FirstColumn To LastColumn
With .Columns(C)
If .Hidden Then
Cap = .Cells(CapRow).Value
If StrComp(Cap, Cmd, vbTextCompare) = 0 Then .Hidden = False
End If
End With
Next C
Else
.Range(.Columns(FirstColumn), .Columns(LastColumn)).Hidden = False
End If
End With
Application.ScreenUpdating = True
End Sub
Look for the two declarations in this procedure:
CapRow = 4
FirstColumn = 3
Row 4 is the row on your data sheet in which the program will look for the months names. Column 3 (= "C") will be the first column in which the program will expect to find a month's name. Columns A:B will never be touched.
Now your system is ready. You will need to know how to operate it.
1. When you select "Show All" from the dropdown all columns starting from FirstColumn will be shown. Call this a reset.
2. When you select any of the items from the dropdown columns with that name in CapRow will be shown.
3. When you select another month it will be added to the one already shown.
4. When all columns are shown already, only the selected one will be displayed.
You can modify the range DropdownList anytime, make it longer or shorter. The important thing is that the names in the dropdown are available in the CapRow. The program compares them as text, meaning "show all" is the same as "SHOW ALL".

Changing columns for Excel userform comboboxes

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.

Resources