Excel Table : add blank columns and headers vba - vba

I have an excel table and I want to add a column to it and then name the header. Somehow my old codes don't work anymore, and I am not sure if it has anything to do with me making the data range a table (Name is Table1). Now the codes run through with no error but only add the blank column but did not add a header. I pressed F8 and it looks like it skips Select portion and jumps to the end.
Table is specified from column A to column AG. I used to be able to insert multiple blank columns and add the headers just fine. Now I don't want to specify cell position and assign a cell value to it (cell(1, 32).value ="Month") since I want to have the flexibility to be add however many columns I need and add the header respectively like before.
Sub Ins_Blank_Cols_Add_Headers()
Columns("AF:AG").Insert Shift:=xlToRight
Columns("AF:AF").Cells(1, 1) = "<<NewHeader>>"
Columns("AG:AG").Cells(1, 1) = "<<NewHeader>>"
Dim cnter As Integer
LastCol = Cells(1, Columns.Count).End(xlToLeft).Column
cnter = 0
For i = 1 To LastCol
If Cells(1, i) Like "<<NewHeader>>*" Then
Select Case cnter
Case 0: Cells(1, i).Value = "Month"
Case 1: Cells(1, i).Value = "Year"
End Select
cnter = cnter + 1
End If
Next i
End Sub

Stop using Range.Select and Selection, it will do you good.
Also always use fully qualified ranges.
Your issue is that when you insert a column in Table, Excel automatically assigns a header name to it.
So your IF condition to check empty fails. Hence No Select case invocation
Change this
Columns("AF:AF").Select
Selection.Insert Shift:=xlToRight
To
Columns("AF:AF").Insert Shift:=xlToRight
Columns("AF:AF").Cells(1, 1) = "<<NewHeader>>" ' In Table Can't set blank header so use a place holder.
Also Change the If Condition from
If IsEmpty(Cells(1, I)) Then
To
If Cells(1, I) Like "<<NewHeader>>*" Then

Related

Creating column immune references in VBA?

I have a project that I am working on where multiple conditions are checked across all rows and many columns. The issue is that columns are added/removed from the sheet, and, at present, that results in all of my cell(row,column) references being off + outputting incorrect information. I'm wondering if there's a way to make my column references more robust so that they automatically find the correct headers and use them when checking? Would a solution to this problem be able to account for multiple columns containing the exact same header text?
Basically:
No blank columns
Column headers have repeats (e.g., Column 1 header: "Financials"; Column 15 header: "Financials")
Columns are shifting right and left based on adding/removing columns from sheet
Please find a short sample of my current code below with notes:
Dim i As Integer
Dim lastRow As Long
Dim lastCol As Long
lastRow = Range("A1").End(xlDown).Row
lastCol = Cells(1, Columns.Count).End(xlToLeft).Column
For i = 2 To lastRow
Select Case Cells(i, 14).Value
Case Is = "Yes"
Select Case True
Case Cells(i, 63).Value = 6 And _
(IsEmpty(Cells(i, 77)) Or IsEmpty(Cells(i, 93)) Or IsEmpty(Cells(i, 109)) Or _
IsEmpty(Cells(i, 125)) Or IsEmpty(Cells(i, 141)) Or IsEmpty(Cells(i, 157)))
Cells(i, 174).Value = "True" '^THESE CELL VALUES ALL HAVE THE SAME COLUMN HEADER TITLE
If the table is consistent - starting at A1 and occupying a contiguous block - then Range("A1").CurrentRegion will reference the table.
You can then use .CreateNames to name the columns (that is, using Named Ranges) according to their headings.
Dim rngTable As Range
Dim rng As Range
Set rngTable = Range("A1").CurrentRegion
rngTable.CreateNames True, False, False, False
' that is, based on the first row headings
Range("Salary").Select 'prove it works
'if necessary, iterate the cells of the column,
For Each rng In Range("Salary")
rng.Value = rng.Value + 10
Next 'rng
If a column heading is duplicated ("Financial"), though, then you'll be asked to confirm and the second occurrence will overrule the first. (Or you could say "No" and the first occurrence will be named.) In which case, it is preferable that you first correct these duplicate headings.
Correcting the duplicate headings is not necessarily straight forward, but something that you should resolve anyway. If it is a specific word "Financials" (or words) that could be duplicated then this makes the task easier. You could count how many occurrences there are, and correct the second, etc., to "Financials2".
One easy way to to assign a Name to the column. Say column N has the header "Payments". First assign the Name "Payments" to that column:
Then in VBA we can code like:
Sub dural()
Dim rng As Range, colly As Long
Set rng = Range("Payments")
colly = rng.Column
For i = 2 To 100
If Cells(i, colly) = "whatever" Then
MsgBox "Help"
End If
Next i
End Sub
The code will continue to work even if you add/remove columns beforre column N.

Return Column Header of Colored Cells

This process is being used for QC purposes. I have a spreadsheet that highlights certain cells that are wrong based off of their values and the validation rules we have in place. I was wonder if there was a way to return the column names of each cell that is colored into column A for each row? So for example if D2, F2, and G2 are wrong it would put all of those column headers in A2 to specify what exactly is wrong. I know it gets a bit more complicated trying to automate stuff with cell colors and I am not experienced in VBA which I'm assuming this will need. Is this possible to do, if so what would be the proper route to take? The data runs from column A to column BS, and the row numbers may differ, so if it could run up to row 1,000 that would be great. Attached is what the data looks like that I am working with.
The red means something is wrong in that row, and the orange cell is the color indicating that it is a wrong value
Yes, it is possible to do. Here is some snippets of code I pulled together to help get you started.
Lastrow = Cells(Rows.count, "A").End(xlUp).Row 'Get last row
With ActiveSheet
Lastcol = .Cells(1, .Columns.count).End(xlToLeft).Column 'Get last col
End With
For x = 1 To Lastcol 'Iterate Col
For i = 1 To Lastrow 'Iterate Row
'if red....
If Cells(i, x).Selection.Interior.Color = 255 then
'Move name to Cell A and append off of old name(s).
Cells(i, "A") = Cells(i, "A") & ", " & Cells(i, x)
End If
Next i 'next row
Next x 'next col

Inserting text to blank row using vba macro in excel

I have a data of say more than 5000 rows and 10 columns. I would like to add a text to the rows based on columns conditions.
A B C D
fname lname state clustername
1. ram giri NCE ...
2. philips sohia MAD ...
3. harish Gabari NCE ....
Based on the column state, for NCE the cluster name is "nce.net" has to be assigned to column D (clustername) and also for MAD is "muc.net" to be assigned to row 2.
could you please help me out.
Here is my code:
dim emptyrow as string
row_number = 1
lastRow = Cells(Rows.Count, "D").End(xlUp).Row
state = sheets("sheet1").rows("C" & row_number)
for each cell in selection
if instr(state, "NCE") = true then
Range(Cells(emptyrow, "D").Value = Array("nce.net")
end if
next emptyrow
Could you please help me out.
Why not a simple formula
In D1 and copy down
=IF(C1="NCE","nce.net",IF(C1="MAD","muc.net","No match"))
Doing the same this with code
Sub Simple()
Dim rng1 As Range
Set rng1 = Range([c1], Cells(Rows.Count, "C").End(xlUp))
With rng1.Offset(0, 1)
.FormulaR1C1 = "=IF(RC[-1]=""NCE"",""nce.net"",IF(RC[-1]=""MAD"",""muc.net"",""No match""))"
.Value = .Value
End With
End Sub
You may create a reference table consisting of unique state and clustername in a seperate worksheet and then pull the clustername into your original sheet using a =VLOOKUP() function ... provided there is a 1:1 relation between state and cluster ... even 1 cluster for multiple states would work. This way you avoid hardcoding and you can react quickly if cluster names change.
Example:
in Sheet2 list all countries and their associated clusternames
in Sheet1 enter =VLOOKUP(...) into first row of clustername column as per below picture and copy down for all rows
Of course you may want to have values only, not formulas in your cluster column; then you can convert formulas into values by copying and then pasting as values that cluster column after you've entered the =VLOOKUP(...) formula.
Alternatively, if e.g. you have a lot of clusternames already defined and only want to work on rows where clustername is blank, you can
filter for blank clusternames and insert the =VLOOKUP(...) only there
use a small piece of code
Sub DoCluster()
Dim R As Range, S As Integer, C As Integer, Idx As Integer
Set R = ActiveSheet.[A2] ' top left cell of table
S = 3 ' column index of State column
C = 4 ' column index of Clustername column
Idx = 1 ' start at 1st row within range
' run a loop across all rows, stop if 1st column gets blank
Do While R(Idx, 1) <> ""
' work only on rows wher cluster not yet set
If R(Idx, C) = "" Then
' now this isn't really good ... try to avoid hardcoding BY ANY MEANS
Select Case R(Idx, 3)
Case "NCE"
R(Idx, 4) = "nce.net"
Case "MAD"
R(Idx, 4) = "muc.net"
' insert other cases here as per need
' ...
' trap undefined cases
Case Else
R(Idx, 4) = "undefined"
End Select
End If
Idx = Idx + 1
Loop
End Sub
Personally I don't like this kind of hardcoding at all, I'd rather take the clusternames from a table ... so for me there wouldn't be a need to write code unless the whole task is much more complex than described.

macro to insert blank rows based on column value

I'm unsuccessfully trying to create a macro to insert blank row based on cell value.
I have a bulk data, in which one column has differing numbers. Based on the column value, I need to insert a blank row below it.
If I understand you properly this should do what you want.
Just change "A:A" to the range your working with and the If cell.Value = 1 Then to the condition you need to find the cell you want to add a blank row under.
Dim i As Range
Dim cell As Range
Set i = Range("A:A")
For Each cell In i.Cells
If cell.Value = 1 Then
cell.Offset(1).EntireRow.Insert
End If
Next
The below is an example for if you are looking to insert a blank row based on a sudden change of value in a column (in this case column "C"):
Dim lRow As Long
For lRow = Cells(Cells.Rows.Count, "C").End(xlUp).Row To 3 Step -1
If Cells(lRow, "C") <> Cells(lRow - 1, "C") Then Rows(lRow).EntireRow.Insert
Next lRow
You can change Cells(lRow - 1, "C") to whatever value you want to trigger your row insert and, of course, what column this is being applied to.

Insert or Delete column if does not equal heading

I have column headings starting in Column L going forward. The column headings need to be in a certain order.
By hand, I have to insert columns so everything is in order. I put insert or delete in the question title because I assume it's easy to go between the two.
I have no idea how to start this. I have code for deleting rows when a observation is appended with "Total". However, how do I change it so it works for columns?
LR = ThisWorkbook.Sheets("Cheese_D").Range("A" & Rows.Count).End(xlUp).Row
With ThisWorkbook.Sheets("Cheese")
For i = LR To 2 Step -1
With ThisWorkbook.Sheets("Cheese").Range("A" & i)
If Right(.Value, 5) = "Total" Then .EntireRow.Delete
End With
Next i
End With
One way to look at columns in a range is like this:
Set rng = Range("L:S")
For Each col In rng.Columns
'do your logic and .EntireColumn.Delete
next
Or look at all columns in sheet like this:
For Each col in ThisWorkbook.Sheets("Cheese").Columns
'your logic
Next
Now to add in your logic:
Set rng = Range("L:S")
For Each col In rng.Columns
If Cells(1, col.Column).Value = "Total" Then col.EntireColumn.Delete
next
These four lines replace all your code in the original post.