I've got part of a solution but it isn't working like I'd hope, so I've come to you for advice.
I regularly receive Excel files where I need to amend formatting. I'm trying to learn VBA by automating as much of these procedures as possible.
One particular format I complete is converting the date to "DDMMYYYY" (09091986), where it usually comes in as 09/09/1986.
Within my worksheet, there are a total of 3 columns containing dates, all of which need the same formatting and all of which have the word "DATE" in the heading. They are not adjacent to each other.
I must also be careful not to have any other data affected, as I have names and addresses which may contain the characters "DATE".
So, background out of the way... I'm trying to search the first row until I find the word "Date" and then format that for each cell until the last row, before moving on to the next column containing the word "DATE" and repeating this until all columns with the word "DATE" have been formatted.
I'm sure you have a simple solution but I can't seem to find it myself.
Here is the code I have...
Sub Dateformat()
Dim LastRow As Integer
Dim FindCol As Integer
Dim C1 As Integer
LastRow = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
FindCol = Cells.Find(What:="DATE", LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Column
For C1 = 2 To LastRow
Cells(C1, FindCol).NumberFormat = "DDMMYYYY"
Next C1
End Sub
This works for the first column containing date but doesn't move on to the next column.
Thanks for the help
Regards,
Adam
As you know, you need to loop through and find each Row Header with DATE
Here is one way to do it.
Sub Dateformat()
Dim wks As Worksheet
Dim LastRow As Integer
Dim FindCol As Range
Dim sAdd As String
Set wks = ThisWorkbook.Sheets("Sheet1") ' adjust as needed
With wks
LastRow = .Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'find first instance where DATE exists in row 1 (headers)
Set FindCol = .Rows(1).Find(What:="DATE", LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
'store address of first found instance (to check in loop)
sAdd = FindCol.Address
Do
'format column (row 2 to last used row)
.Range(.Cells(2, FindCol.Column), .Cells(LastRow, FindCol.Column)).NumberFormat = "DDMMYYYY"
'this line works as well and is a bit cleaner
'.Cells(2, FindCol.Column).Resize(LastRow - 1, 1).NumberFormat = "DDMMYYYY"
'find next instance (begin search after current instance found)
Set FindCol = .Cells.FindNext(After:=FindCol)
'keep going until nothing is found or the loop finds the first address again (in which case the code can stop)
Loop Until FindCol Is Nothing Or FindCol.Address = sAdd
End With
End Sub
Related
I'm trying to copy data from a column in a sheet called "KPI", in cells H6:H100, to a specific row in a sheet named "table". The row depends on two variables in the KPI sheet which user selects from drop downs in C2:D2.
I have managed to get the code to find the right row each time by searching columns A then B in the "data" sheet.But when it comes to the copy paste/transpose column H from "KPI" sheet into the right row on the "table" sheet it throws up a 424 error.
I might be missing something really obvious so any help is appreciated.
Sub copy_transpose()
Dim rng_source As Range
Dim Found As Range, Firstfound As String
Dim rngSearch As Range
Dim Criteria As Variant
Set rng_source = ThisWorkbook.Sheets("KPI").Range("H6:H100")
Set rngSearch = Sheets("Table").Range("A:A")
Criteria = Sheets("KPI").Range("C2:D2").Value
Set Found = rngSearch.Find(What:=Criteria(1, 1), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Found Is Nothing Then
Firstfound = Found.Address
Do
If Found.EntireRow.Range("B2").Value = Criteria(1, 2) Then Exit Do 'Match found
Set Found = rngSearch.FindNext(After:=Found)
If Found.Address = Firstfound Then Set Found = Nothing
Loop Until Found Is Nothing
End If
If Not Found Is Nothing Then
Application.Goto Found
rng_source.Copy
Sheets("Table").Range(cell.Offset(0, 1), cell.Offset(0, 7)).PasteSpecial Transpose:=True
Else
MsgBox ("Error")
End If
End Sub
I needed more coffee. I hadn't spotted that is was referencing "cell" instead of "found".
Today I learned that "cell" is not a vba function, and was actually something I had dimensioned in my older code, and was the equivalent of "found".
I need to find the value "5005" (only this value) in column J:J, insert a new row below it, and then fill the row with values in columns A-U.
I am new to VBA and I am unable to do this without making a mess of code.
The draft would look something like this
Find all cells with value 5005 in column J:J,
Insert Row below,
Put value1 in A,
Put Value2 in B,
etc.... until column U,
Repeat on the next cell that has "5005" in it until there are no more
I am unsure what code would work best at this point and I think seeing this written out by a pro would help significantly.
In the messy code I've provided below I was able to search for the value "5005" and insert a line below it, but whatever cell I have selected in excel will be filled with the value "TRUE" and the code is quite messy. Not sure If I was going the right direction with it.
Sub AAAAAAAtest()
Dim find5005 As Range
'Have excel search 1 column instead of all cell
Set find5005 = Cells.Find(What:="5005", LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, MatchCase:=True, SearchFormat:=False)
If find5005 Then ActiveCell.Value = find5005.Offset(1).EntireRow.Insert
End Sub
Narrative is in the code comments
Option Explicit
Sub insert5005()
Dim rng As Range, urng As Range, faddr As String
Dim vals As Variant
'get some dummy values quickly
vals = buildAU()
With Worksheets("sheet5")
'find first 5005
Set rng = .Range("J:J").Find(What:="5005", after:=.Cells(.Rows.Count, "J"), _
LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext)
'continue if found
If Not rng Is Nothing Then
'record first found cell
faddr = rng.Address
'start loop for insert, populate and additional cells
Do
'insert new row
rng.Offset(1, 0).EntireRow.Insert
'populate row
.Cells(rng.Offset(1, 0).Row, "A").Resize(1, UBound(vals) + 1) = vals
'look for another
Set rng = .Range("J:J").FindNext(after:=rng)
'keep going until first address is reached a second time
Loop Until rng.Address = faddr
End If
End With
End Sub
Function buildAU()
'construct some dummy values
Dim i As Long, tmp As String
For i = 65 To 85
tmp = tmp & Format(i, "|v\alu\e00")
Next i
buildAU = Split(Mid(tmp, 2), Chr(124))
End Function
I have an excel spreadsheet which generate different column names every time, but has the same starting word.
So for example, I could have a column with the name "Key" , after 2 to three columns there would columns with names as key3,key29 likewise I have another word called value and then value1,value2 after some columns value6,value7 etc
What I want to do is to search the columns names in the sheet Rows("1:1").Select and select the entire column if a text matches to the value I assign and finally copy it to separate sheet.
So far this is what I tried.
Rows("1:1").Select 'Selecting the columns row
' Finding values with name i want to look for
Selection.Find(What:="key", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate.Select
Option Explicit
Sub test()
Dim cell As Range, rng As Range
Dim SearchString As String
Dim LastColumn As Long
SearchString = "Test"
With ThisWorkbook.Worksheets("Sheet1")
Set rng = .Rows("1")
For Each cell In rng.Cells
If InStr(1, cell.Value, SearchString) > 0 Then
LastColumn = ThisWorkbook.Worksheets("Sheet2").Cells(1, ThisWorkbook.Worksheets("Sheet2").Columns.Count).End(xlToLeft).Column
.Columns(cell.Column).Copy ThisWorkbook.Worksheets("Sheet2").Columns(LastColumn + 1)
End If
Next
End With
End Sub
The code below will give a great start. Adjust any worksheet, cell and range references as needed. There's also a ton of resources on what each method I used does in case anything is unfamiliar to you.
With Worksheets("Sheet1")' change as needed
Dim lastRow as Long
lastRow = .Cells(.Rows.Count,1).End(xlUp).Row 'change column as needed
Dim headers as Range
Set headers = .Range("A1",.Cells(1,.Columns.Count).End(xlToLeft))
Dim findIt as String
findIt = "key"
Dim cel as Range
For each cel in headers
If cel.Text like "*key*" Then
.Range(cel,.Cells(lastRow, cel.Column)).Copy worksheets("sheet2").Cells(1,cel.Column) 'change sheet and column as needed
End if
Next
End With
In Column L (only) I want to replace any instance of data with "True" regardless of what was originally in any of the Column L cells. The code I tried was:
With ActiveSheet
intLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Let strSelectRange = "L2" & ":" & "L" & intLastRow
Range(strSelectRange).Select
Cells.Replace What:="*", Replacement:="True", LookAt:=xlPart _
, SearchOrder:=xlByColumns, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
End With
First, I used .Rows.Count, "A" because in that column every row has data so I know how many rows to go down in Column L. In Column L many cells will be blank.
When I run this, every cell in the entire worksheet that has anything in it, is changed to True, not just the data in Column L.
Another method I tried was:
Range("L2:L1200").Select
Selection.Replace What:="*", Replacement:="True", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Range("A1").Select
What I don't like about this is that I picked L1200 as the number of rows just to be sure I'd search farther than the actual last row that can contain data. I'm worried that this method might cause some kind of problem at some point.
What I'd really like to know is what I'm doing wrong in the first code example.
Thanks for any help you can offer!!!
Search & Replace in Column
Use Option Explicit always, to quicker learn about the occurring
errors and to be forced to declare variables.
You should always declare your rows as Long.
When you use the With statement you use the dots on everything, even
on .Range and .Cells etc. The code might work in this case
(ActiveSheet) anyway, but it is incorrect.
Avoid the use of ActiveSheet, use the worksheet name.
Avoid the use of Select. There are many posts (articles) about this.
When ever you use Cells without anything behind it, it refers to all the
cells in the worksheet.
The first thing in the Replace function (Find function) is the range
where you're going to Replace (Find, Search). It can be a column, it
can be Cells or just a smaller range.
The Code
Sub SROneColumn()
Const cVntLRColumn As Variant = "A" ' Last Row Column Letter/Number
Const cVntCriteria As Variant = "L" ' Criteria Column Letter/Number
Const cLngFirstRow As Long = 2 ' First Row Number
Const cStrReplace As String = "True" ' Replace String
Dim lngLastRow As Long ' Last Row Number
Dim strSelectRange As String ' Select Range Address
With ActiveSheet
lngLastRow = .Cells(.Rows.Count, cVntLRColumn).End(xlUp).Row
strSelectRange = .Range(.Cells(cLngFirstRow, cVntCriteria), _
.Cells(lngLastRow, cVntCriteria)).Address
.Range(strSelectRange).Replace What:="*", Replacement:=cStrReplace, _
LookAt:=xlPart, SearchOrder:=xlByColumns, MatchCase:=False
End With
End Sub
An interesting way to use a worksheet without the use of an object variable:
Sub SRSheet()
Const cStrSheet As Variant = "Sheet1" ' Worksheet Name/Index
With ThisWorkbook.Worksheets(cStrSheet)
End With
End Sub
Range(strSelectRange).Select
selects a range (though best to avoid Select) but then your code does nothing with that selection because Cells is the entire sheet.
Maybe you want instead:
Range(strSelectRange).Replace What:="*", Replacement:="True", LookAt:=xlPart
I am currently having issues with a Macro I am programming for Excel 2013 regarding reading hidden columns. I am trying to utilize Column A as a row of unique keys to allow me to quickly develop logic that hides and shows a row based on the key value in column A. When I hide column A manually in the sheet for visual purposes I am then unable to read from that column, aka my code returns an error. If I show the column the code executes clearly. Thanks in advance for the help!
Public Sub hideRow(findId As String, sheetName As String)
Dim lastRow As Long
Dim foundCell As Range
Dim hideThisRowNum As Integer
'Get Last Row
lastRow = Worksheets(sheetName).Range("A" & Rows.Count).End(xlUp).Row
'Find ID
With Worksheets(sheetName).Range("a1:a1000") 'This needs to be A1 to AxlDown
Set foundCell = Worksheets(sheetName).Range("A1:A" & lastRow).Find(What:=findId, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
End With
'Get Row # to Hide
hideThisRowNum = Val(foundCell.Row)
'Hide row
Worksheets(sheetName).Rows(hideThisRowNum).Hidden = True
'Set Add To Action Plan = No
Worksheets(sheetName).Range("G" & hideThisRowNum).Value = "No"
End Sub
The problem is in the .Find() call. Using LookIn:=xlValues won't find hidden cells. Change it to LookIn:=xlFormulas and it should work.