Unable to match up the column name - vba

I'm searching for the column name but my code is not working. This is what I have tried :
word = "sample"
Set aCell = ActiveSheet.Rows(1).Find(What:=word, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
lastRow = Cells(1, Columns.count).End(xlToLeft).Column
For k = 0 To lastRow
If aCell Is Nothing Then
aCell.Offset(0, 1).EntireColumn.Delete
End If
Next k
All I want to do is to delete the entire column if it is found. Any help ?

You could do it this way:
Sub deleteColumn()
Dim headerColumnToDelete As String
Dim endRow As Integer
Dim counter As Integer
endRow = Cells(1, Columns.Count).End(xlToLeft).Column
headerColumnToDelete = "sample"
For counter = endRow To 1 Step -1
If Cells(1, counter) = headerColumnToDelete Then
Cells(1, counter).EntireColumn.Delete
End If
Next counter
End Sub

If you want to delete the whole column with the column heading "sample", try this in a Module:
Public Sub DeleteSample()
DeleteColumn ("sample")
End Sub
Public Sub DeleteColumn(Name As String)
'Get the header row
Dim row As Range
Set row = Rows(1)
'Find the cell containing Name in that row
Dim result As Range
Set result = row.Find(Name)
Dim wholeColumn As Range
'Select the whole column (or quit if it's not found)
On Error GoTo Catch
Set wholeColumn = result.EntireColumn()
On Error GoTo 0
'Delete the whole column and shift cells left
wholeColumn.Delete xlShiftToLeft
Catch:
Exit Sub
End Sub
You don't need a For-loop at all, you can just use the Excel API to find the cell :)

Sub columndelete()
Dim lastcolumn As Long
word = "sample"
lastcolumn = Cells(1, Columns.Count).End(xlToLeft).Column
For i = 1 To lastcolumn
If Cells(1, i).Value = word Then
Cells(1, i).EntireColumn.Delete
End If
Next i
End Sub

Just made some changes in your code:
Sub test()
word = "sample"
Set acell = ActiveSheet.Rows(1).Find(What:=word, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not (acell Is Nothing) Then
acell.EntireColumn.Delete
End If
End Sub

Related

Copying values from dynamic cells to specifically named columns

I want to import values from a dynamic worksheet to our "Database" sorted by the title of the column. As you can see I have scraped together something that works, but it is very slow and doesn't copy just the values.
The first row of the sheet is the titles, the second and further down rows are the values I want to copy.
Sub Copypasta()
Sheets("copypasta").Select
Sheets("copypasta").Range("A2").Activate
While Not ActiveSheet.Cells(1, ActiveCell.Column) = ""
t1 = ActiveSheet.Cells(1, ActiveCell.Column)
Selection.Copy
Set MyActiveCell = ActiveCell
Sheets("Database").Activate
lnCol = Sheets("Database").Cells(1, 1).EntireRow.Find(What:=t1, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False).Column
lnRow = Sheets("Database").Range("a65536").End(xlUp).Row
If lnCol > 1 Then Sheets("Database").Cells(lnRow, lnCol).Activate Else Sheets("Database").Cells(lnRow, lnCol).Offset(1, 0).Activate
ActiveSheet.Paste 'xlPasteValues
Sheets("copypasta").Activate
MyActiveCell.Offset(0, 1).Activate
Wend
End Sub
I tried to use PasteSpecial xlPasteValues or setting the value of the cell directly, but I can't get it to work. I am googling every error it throws and then search the code for where the error occurs.
Try the code below:
Option Explicit
Sub Copypasta()
Dim CopySht As Worksheet
Dim DBSht As Worksheet
Dim i As Long, lnCol As Long, lnRow As Long
Dim MyActiveCell As Range, FindRng As Range
Dim t1
' set the Worksheet objects
Set CopySht = ThisWorkbook.Sheets("copypasta")
Set DBSht = ThisWorkbook.Sheets("Database")
' set the anchor position on the loop
Set MyActiveCell = CopySht.Range("A2")
' loop through columns at the first row (until you reach a column that is empty)
While CopySht.Cells(1, MyActiveCell.Column) <> ""
t1 = CopySht.Cells(1, MyActiveCell.Column)
MyActiveCell.Copy
With DBSht
lnRow = .Cells(.Rows.Count, "A").End(xlUp).Row ' find last row with data in Column "A"
Set FindRng = .Rows(1).Find(What:=t1, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False)
If Not FindRng Is Nothing Then ' check if Find was successful
lnCol = FindRng.Column
Else
lnCol = 1
End If
' there's no need to use Select and Activate to Copy and/or Paste
.Cells(lnRow + 1, lnCol).PasteSpecial xlPasteValues
End With
Set MyActiveCell = MyActiveCell.Offset(0, 1) ' loop one column to the right
Wend
End Sub

VBA Excel - Filling out the spaces between two cells with the value of a third one

some time ago I posted a similar question here and got a great answer. But now I would need a slightly altered code but I am not able to change it up.
In an Excel sheet I have cells which have values but all cells between those two are empty. I want Excel to fill the empty cells between them with the values of a third cell. To visualise:
That's what it looks like
Now I want the macro to fill out all the empty cells with the value of the corresponding J cell. So it would look like this:
From the previous thread I used this code:
Sub main()
Dim cell As Range
For Each cell In Intersect(Columns(1), ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).EntireRow)
With cell.EntireRow.SpecialCells(xlCellTypeConstants)
Range(.Areas(1), .Areas(2)).Value = .Areas(1).Value
End With
Next
End Sub
Is it possible to change up the existing code? Or maybe the other code from my previous, linked question? I looked into both but I myself unfortunately wasn't able.
Any help is appreciated. Thanks in advance.
Use the code from the your other question but change rowval to look at column J
Option Explicit
Sub test_DTodor()
Dim wS As Worksheet
Dim LastRow As Double
Dim LastCol As Double
Dim i As Double
Dim j As Double
Dim k As Double
Dim RowVal As String
Set wS = ThisWorkbook.Sheets("Sheet1")
LastRow = LastRow_1(wS)
LastCol = LastCol_1(wS)
For i = 1 To LastRow
For j = 1 To LastCol
With wS
If .Cells(i, j) <> vbNullString Then
'1st value of the row found
RowVal = .Cells(i, 10).Value --This is all I changed
k = 1
'Fill until next value of that row
Do While j + k <= LastCol And .Cells(i, j + k) = vbNullString
.Cells(i, j + k).Value = RowVal
k = k + 1
Loop
'Go to next row
Exit For
Else
End If
End With 'wS
Next j
Next i
End Sub
Public Function LastCol_1(wS As Worksheet) As Double
With wS
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
LastCol_1 = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Else
LastCol_1 = 1
End If
End With
End Function
Public Function LastRow_1(wS As Worksheet) As Double
With wS
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
LastRow_1 = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
LastRow_1 = 1
End If
End With
End Function
Answer with modifying previous code
Sub main()
Dim cell As Range
For Each cell In Intersect(Columns(1), ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).EntireRow)
With cell.EntireRow.SpecialCells(xlCellTypeConstants)
Range(.Areas(1).Offset(, 1), .Areas(2).Offset(, -1)).Value = Cells(.Areas(1).Row, "J").Value
End With
Next
End Sub
Assuming you have three values in each row and they are not consecutive, a small change to your original code should suffice.
Sub main()
Dim cell As Range
For Each cell In Intersect(Columns(1), ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants).EntireRow)
With cell.EntireRow.SpecialCells(xlCellTypeConstants)
Range(.Areas(1).Offset(, 1), .Areas(2).Offset(, -1)).Value = .Areas(3).Value
End With
Next
End Sub
This will do exactly what you want in three lines
Sub FillBlanks()
Dim c
For Each c In ActiveSheet.UsedRange.Columns("J").SpecialCells(xlCellTypeConstants)
Range(c.Offset(0, c.End(xlToLeft).Column - c.Column), c.Offset(0, -c.Column + 1)).SpecialCells(xlCellTypeBlanks).Value2 = c.Value2
Next c
End Sub

Selecting only Cells with Value VBA

I have the code below and works fine, but I only want to copy cells with Values. I have blank data in the middle, as I will delete that does not make sense to copy them too.
Sub FindAgain()
'
' FindAgain Macro
'
Dim Ws As Worksheet
Dim LastRow As Long
AC = ActiveCell.Column
Set Ws = Worksheets("Sheet1")
LastRow = Ws.Cells(Rows.Count, "B").End(xlUp).Row
Cells.Find(What:="Scenario", After:=ActiveCell, LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
ActiveCell.Offset(1, 0).Select
Range(ActiveCell, Cells(LastRow, AC)).Select
End Sub
Any idea how I can better write it? With Loop maybe? Thanks!
I assume that after Range(ActiveCell, Cells(LastRow, AC)).Select you see a region selected that you want to copy ignoring blank cells. One way to go about it is to iterate over all the cells in Selection, check if they are not empty and copy them:
Dim c As Range
Dim i As Long
' store current row for every column separately
Dim arrRowInCol() As Long
ReDim arrRowInCol(Selection.Column To Selection.Column + Selection.Columns.Count - 1)
For i = LBound(arrRowInCol) To UBound(arrRowInCol)
' init the first row for each column
arrRowInCol(i) = Selection.Row
Next i
For Each c In Selection
If Len(Trim(c)) <> 0 Then
c.Copy Destination:=Sheets("Sheet2").Cells(arrRowInCol(c.Column), c.Column)
arrRowInCol(c.Column) = arrRowInCol(c.Column) + 1
End If
Next c
Found a way to do what I want: At least is working, i am newby so, for you guys may seem funny or bad, for me is great =D
Sub FindAgain()
'
' FindAgain Macro
'
Dim Ws As Worksheet
Dim LastRow As Long
Dim c As Range
Dim i As Integer
Dim j As Integer
AC = ActiveCell.Column
Set Ws = Worksheets("Sheet1")
LastRow = Ws.Cells(Rows.Count, "B").End(xlUp).Row
i = 15
j = 7
Cells.Find(What:="Scenario", After:=ActiveCell, LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
ActiveCell.Offset(1, 0).Select
Range(ActiveCell, Cells(LastRow, AC)).Select
For Each c In Selection
If Len(Trim(c)) <> "" Then
c.Copy Destination:=Sheets("Sheet1").Cells(i, j)
End If
If c = "" Then
i = i
Else
i = i + 1
End If
j = j
Next c
End Sub
I will start with your code, which actually tries to select the ranges. This is what I have built upon it:
Option Explicit
Public Sub FindMe()
Dim my_range As Range
Dim temp_range As Range
Dim l_counter As Long
Dim my_list As Object
Dim l_counter_start As Long
Set my_list = New Collection
l_counter_start = Cells.Find(What:="Scenario", After:=ActiveCell, LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Row + 1
For l_counter = l_counter_start To Worksheets("sheet1").Cells(Rows.Count, "B").End(xlUp).Row
If Cells(l_counter, 2) <> "" Then my_list.Add (l_counter)
Next l_counter
For l_counter = 1 To my_list.Count
Set temp_range = Range(Cells(my_list(l_counter), 2), Cells(my_list(l_counter), 4))
If my_range Is Nothing Then
Set my_range = temp_range
Else
Set my_range = Union(my_range, temp_range)
End If
Next l_counter
my_range.Select
End Sub
It works upon a scenario like this:
Pretty much it works like this:
We declare two ranges.
The range my_range is the one to be selected at the end.
The range temp_range is only given, if there is a value in the second column.
Then there is a union of both ranges, and my_range is selected at the end of the code.

Range.Find type mismatch error

Here's my code:
Need my code to enter TRUE in a cell if it finds a value in column A of sheet "Itemschedule" to be present in column B of sheet "Whereused". Getting "Type mismatch" error. If I change the "st = Sheets(..." line to .Value instead of .Text, or if I change the .Find line to LookIn:=xlFormulas instead of Lookin:=xlValues, it gives the same error irrespective of the combination of the two.
Private Sub CommandButton1_Click()
Dim rowLast As Integer
Dim str As String
Dim cell As Range
Sheets("Itemschedule").ListObjects("Table2").Range.AutoFilter
rowLast = Sheets("Itemschedule").Cells(Rows.Count, "A").End(xlUp).Row
Sheets("Itemschedule").ListObjects("Table2").Resize Range("A1:E" & rowLast)
Sheets("Itemschedule").Range("A" & rowLast + 1 & ":E" & Rows.Count).ClearContents
For i = 2 To rowLast
str = Sheets("Itemschedule").Cells(i, "A").Text
With Sheets("Whereused").Range("B:B")
Set cell = .Find(What:=str, After:=.Range("B1"), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
End With
If cell Is Nothing Then
Sheets("Itemschedule").Cells(i, "E").Value = "FALSE"
Else
Sheets("Itemschedule").Cells(i, "E").Value = "TRUE"
End If
Next
On Error Resume Next
Sheets("Itemschedule").ListObjects("Table2").Range.AutoFilter
Sheets("Itemschedule").Range("A1:E" & rowLast).AutoFilter Field:=1, Criteria1:="FALSE"
Sheets("Itemschedule").Range("A1:E" & rowLast).SpecialCells(xlCellTypeVisible).EntireRow.Delete
Sheets("Itemschedule").ListObjects("Table2").Resize Range("A1:E" & rowLast)
Sheets("Itemschedule").ListObjects("Table2").Range.AutoFilter
End Sub
I have tried a lot but am not able to figure it out. I'm sure it's something silly.
Please help.
Your error is due to the fact that the After parameter is not inside the range you are searching. This part:
With Sheets("Whereused").Range("B:B")
Set cell = .Find(What:=str, After:=.Range("B1"), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
End With
should be:
With Sheets("Whereused").Range("B:B")
Set cell = .Find(What:=str, After:=Sheets("Whereused").Range("B1"), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
End With
otherwise the .Range("B1") is relative to Range("B:B") and therefore refers to C1.
Dictionaries are more efficient at finding duplicate values.
Sub CommandButton1_Click()
Dim keyword As String, keyvalue As Variant
Dim rowLast As Long, x As Long
Dim dicItems
Set dicItems = CreateObject("scripting.dictionary")
With Sheets("Whereused")
rowLast = .Cells(Rows.Count, "A").End(xlUp).Row
For x = 2 To rowLast
keyword = .Cells(x, 2)
keyvalue = .Cells(x, 2)
'Add Key Value pairs to Dictionary
If Not dicItems.Exists(keyword) Then dicItems.Add keyword, keyvalue
Next
End With
With Sheets("Itemschedule")
rowLast = .Cells(Rows.Count, "A").End(xlUp).Row
For x = 2 To rowLast
keyword = .Cells(x, 1)
.Cells(x, 2) = dicItems.Exists(keyword)
Next
End With
End Sub
But the proper way to do it place a WorkSheet Formula in Itemschedule Column B.
=COUNTIF(Table1[[#This Row],[Items]],Table2[[#Headers],[Items]])>0

Count all rows in a column

I am searching for a column in vba that has a certain header and then when I find that I want to search all the rows in that column and replace all the X's with 1's. I have all the code written but for some reason its not allowing the line shown below:
r2 = Range(i, i).EntireColumn.Rows.Count
Sub PA_Change()
Dim i As Long, r As Range, rRow As Range, r2 As Long
Set r = Range("A1")
Set rRow = r.EntireRow
For i = 1 To rRow.Columns.Count
If Cells(1, i) = PA_REQUIRED Then
r2 = Range(i, i).EntireColumn.Rows.Count
For j = 1 To r2
If Cells(j, i).Value = "X" Then
Cells(j, i).Value = "1"
End If
Next j
End If
Next i
End Sub
Try replacing all your code with this and let us know if that works:
*replace the "boo" in searchFor with the actual header name / PA_REQUIRED
Sub PA_Change()
Dim searchFor As String
searchFor = "boo"
Dim grabColumn As Range
Set grabColumn = Rows("1:1").Find(What:=searchFor, _
After:=Range("A1"), LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, MatchCase:=False, _
SearchFormat:=False)
If Not grabColumn Is Nothing Then
Dim entireColumn As Range
Set entireColumn = Range(grabColumn.Address & ":" & Split(grabColumn.Address, "$")(1) & Range(Split(grabColumn.Address, "$")(1) & Rows.Count).End(xlUp).Row)
Dim cell As Range
For Each cell In entireColumn
If UCase(cell) = "X" Then
cell = "1"
End If
Next
Else
Exit Sub ' not found
End If
End Sub