How to get all values of first row of excel - vba - excel

I want to get all values (not empty) of first row of excel .
oBook.Sheets("Sheet1").Rows(1).End(xlDown).column
but I think this is wrong.
I want to loop it and show value inside a MsgBox.

Loop Through the Cells of the Header Row
Dim ws As Worksheet: Set ws = oBook.Sheets("Sheet1")
Dim hrg As Range
Set hrg = ws.Range("A1", ws.Cells(1, ws.Columns.Count).End(xlToLeft))
Dim hCell As Range
For Each hCell In hrg.Cells
MsgBox hCell.Address(0, 0) & " = " & hCell.Value
Next hCell

as per your wording, you need "all values (not empty) of first row of excel" sheet.
you can then use:
WorksheetFunction.CountA() function to count the number of not empty
cell in a range
SpecialCells() method of Range object to select not empty cells
as follows:
With oBook ' reference your workbook
With .Worksheets("Sheet1") ' reference "Sheet1" worksheet of referenced workbook
With .Range("A1", .Cells(1, .Columns.Count).End(xlToLeft)) ' reference row 1 range from column 1 rightwards to last not empty cell in referenced worksheet
If WorksheetFunction.CountA(.Cells) > 0 Then ' if at least one not empty cell
Dim cel As Range
For Each cel In .SpecialCells(XlCellType.xlCellTypeConstants) ' loop thorugh referenced range not empty cells
Debug.Print cel.Value
Next
End If
End With
End With
End With

Related

Select each of 'filtered' values in a column of Sheet 1 and find their occurences in all values of a column in Sheet 2

I have an Excel worksheet comprised of two sheets.
One (Sheet 1) with a list of products, their respective serial numbers and a part number for a specific part - the users enters one or more serial numbers to filter the complete big list to end up with a smaller list of items
One seperate sheet (Sheet 2) that has only one column, a list of part numbers that need to be replaced
Now I want to write a VBA script that on Worksheet_Calculate() (not reflected below) compares the filtered values of a specific column in Sheet 1 (the column containing the part numbers) with the list/column in Sheet 2 and shows a message box for each product containing a part with a number found in the list of sheet2
But I'm having trouble finding a solution for collecting all filtered cells in Sheet 1
I assume I have to somehow make use of the ListObjects property to collect the specific visible/filtered cells and to compare only those to the list in sheet 2
But I don't really know how to select those specific, auto-filtered, cells or write an iteration that accounts for only those cells but still compares to all rows in the list/column of sheet 2
Right now, despite making use of col1 and col2 as ranges with the 'SpecialCells(xlCellTypeVisible)' attribute it always selects all cells of col1
I'm surprised that this selector
prod1 = Cells(r, col1.Column).Value
despite using col1 (which is a limited range) iterates all values, not just the filtered ones
Sub CompareTwoColumns()
Dim col1 As Range, col2 As Range, prod1 As String, lr As Long
Dim incol1 As Variant, incol2 As Variant, r As Long
Set col1 = ActiveSheet.ListObjects("Tabel1").ListColumns.DataBodyRange.SpecialCells(xlCellTypeVisible)
Set col2 = Worksheets("Tabel2").Range("A1").CurrentRegion.SpecialCells(xlCellTypeVisible)
lr = Worksheets("Tabel1").UsedRange.Rows.Count
Dim cell As Range
For r = 2 To lr
prod1 = Cells(r, col1.Column).Value
If prod1 <> "" Then
Set incol2 = col2.Find(prod1, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=True)
If incol2 Is Nothing Then
MsgBox CStr(prod1) + " Not in List"
Else
MsgBox CStr(prod1) + " Is in List!"
End If
End If
Next r
End Sub
Anyone able to nudge me in the right direction?
Match Value in Range
Adjust the worksheet, table, and column names.
Option Explicit
Sub ComparePartNumbers()
' Often you loop through the cells of the destination worksheet
' and try to find a match in the source worksheet (read, copy from)
' and then in another column of the destination worksheet you write
' e.g. Yes or No (write, copy to).
' The analogy doesn't quite apply in this case but I used it anyway.
' Reference the workbook ('wb').
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the source range ('srg').
Dim sws As Worksheet: Set sws = wb.Worksheets("Sheet2")
Dim sTbl As ListObject: Set sTbl = sws.ListObjects("Table2")
Dim sLc As ListColumn: Set sLc = sTbl.ListColumns("Part Number")
Dim srg As Range: Set srg = sLc.DataBodyRange
' Attempt to reference the destination range ('drg').
Dim dws As Worksheet: Set dws = wb.Worksheets("Sheet1")
Dim dTbl As ListObject: Set dTbl = dws.ListObjects("Table1")
Dim dLc As ListColumn: Set dLc = dTbl.ListColumns("Part Number")
Dim drg As Range
On Error Resume Next
Set drg = dLc.DataBodyRange.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
' Validate the destination range.
If drg Is Nothing Then ' no visible cells
MsgBox "No filtered values.", vbCritical
Exit Sub
'Else ' there are visible cells; do nothing i.e. continue
End If
' Declare additional variables.
Dim dCell As Range ' current destination cell
Dim dPartNumber As String ' current part number read from the cell
Dim sIndex As Variant ' the n-th cell where the value was found or an error
' Loop.
For Each dCell In drg.Cells
dPartNumber = CStr(dCell.Value)
If Len(dPartNumber) > 0 Then ' is not blank
sIndex = Application.Match(dPartNumber, srg, 0)
If IsNumeric(sIndex) Then ' is a match
'MsgBox "'" & dPartNumber & "' is in list!", vbInformation
Debug.Print "'" & dPartNumber & "' is in list!"
Else ' is not a match (VBA: 'Error 2042' = Excel: '#N/A')
'MsgBox "'" & dPartNumber & "' is not in list!", vbExclamation
Debug.Print "'" & dPartNumber & "' is not in list!"
End If
'Else ' is blank; do nothing
End If
Next dCell
End Sub

EXCEL: How to combine values from two different column into one new column on different sheet

i am stuck with my procject again... I tried with formulas but i can t make it work or i can t make it right, and i couldn t find similar topic any where, here is the problem. As u can see in screenshot in this link https://ibb.co/FJRBxcM i have 2 worksheets, Sheet1 with some value generator, and Sheet"RadniNalog" where i copy&paste manualy certan values from Sheet1. My goal is to make it work automatically, when i paste data from another Workbook, as shown in screenshot example, i polulate range "A10:C27", range width is constant, always 3 column, but rows can change so number is X. Now i need values from "A10:A27" to copy to next empty column from left to right in Sheet"RadniNalog" from cells in 2nd row. Next i also need to copy Value from cell =F$13$ into the first row in sheet "RadniNalog" (on screenshot example its cell "E1" and that value from F13 needs to act like a Header for values belove it. If Value from header is the same as value in cell "F13" i need to continue adding values under existing ones, and if not move to the next available column. In screenshot example, if cell "D1" from sheet "RandiNalog" is same as cell "F13" in Sheet1, then values from range "A10:A27" should be added under last value in ColumnD. I need some VBA code if possible to make it work as wanted. Thanks in advance
Copy this code to Sheet1 module
This code runs the macro copyValuesToWs when you put the code in F13
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("F13:G13")) Is Nothing Then
Application.ScreenUpdating = False
Application.EnableEvents = False
Call copyValuesToWs
Application.EnableEvents = True
Application.ScreenUpdating = True
End If
End Sub
Create a new module and insert this code
Option Explicit
Function FindLastRow(ByVal Col As Byte, ws As Worksheet) As Long
FindLastRow = ws.Cells(Rows.Count, Col).End(xlUp).Row
End Function
Function FindLastColumn(ByVal rw As Byte, ws As Worksheet) As Long
FindLastColumn = ws.Cells(rw, Columns.Count).End(xlToLeft).Column
End Function
Sub copyValuesToWs()
Dim ws1 As Worksheet: Set ws1 = Sheets("Sheet1")
Dim ws2 As Worksheet: Set ws2 = Sheets("Radni nalog")
Dim lCol As Long
Dim lRow As Long
Dim srcRng As Range
Dim dstRng As Range
Dim hdRng As Range
' Next row after ID
Dim idRng As Range: Set idRng = ws1.Range("A10")
' find last row value in column A
lRow = FindLastRow(1, ws1)
' range to be copied
Set srcRng = ws1.Range(ws1.Cells(idRng.Row, 1), ws1.Cells(lRow, 1))
' find last used column in sheet2
lCol = FindLastColumn(1, ws2)
' header range
Set hdRng = ws2.Range(ws2.Cells(1, 1), ws2.Cells(1, lCol))
' check if value exists in header
On Error Resume Next
Dim sValue As Double: sValue = Application.WorksheetFunction.Match(ws1.Range("F13").Value, hdRng, 0)
If Err.Number = 0 Then ' value exists
' find last row
Set dstRng = ws2.Cells(FindLastRow(sValue, ws2) + 1, sValue)
' paste values
srcRng.Copy
dstRng.PasteSpecial xlPasteValues
Else
' set destination range
Set dstRng = ws2.Cells(2, lCol + 1)
' set header value
ws1.Range("F13:G13").Copy
ws2.Cells(1, lCol + 1).PasteSpecial xlPasteValues
' paste values
srcRng.Copy
dstRng.PasteSpecial xlPasteValues
End If
On Error GoTo 0
Application.CutCopyMode = False
End Sub

How to reference last used column in a certain row and paste certain value in there

I am working on a macro that loops over a the used range in one sheet (which is the last sheet in the workbook) in a certain column ("H"). The macro should then copy the value, only if it is not 0, and paste it in a sheet called "Overview" in the original row, offset by 3 (e.g. first row becomes 4th row) and in the column behind the last used column in row 5. (I hope that makes sense?). I already worked on some code but I did not manage to reference the last used column correctly and am honestly close to a breakdown.
can someone explain to me what I am doing wrong?
This is what I already have:
Dim Cell As Range, cRange As Range, lrw As Long
Dim wsDestination As Worksheet, wsSource As Worksheet
'set worksheets
With ThisWorkbook
Set wsSource = .Worksheets(Sheets.Count)
Set wsDestination = .Worksheets("Overview")
End With
LastRow1 = wsSource.Cells(Rows.Count, "H").End(xlUp).Row
LastColumn1 = wsDestination.Cells(5, "A").End(xlRight).Column
Set cRange = wsSource.Range(wsSource.Cells(1, 8), wsSource.Cells(LastRow1, 8))
For Each Cell In cRange.Cells
If Cell.Value > 0 Then wsDestination.Cells(Cell.Row, LastColumn1).offset(3, 1) = Cell.Value
Next Cell
End Sub```
The Subtle Differences in Ways of Finding the 'Last Column'
To successfully test the first procedure, in a new worksheet you have to:
write a value in cell A1,
write ="" in cell B1,
write a value in cell C1,
hide column C
and use a fill color in cell D1.
The result of the test will be shown in the Immediate window CTRL+G.
The third procedure is an example of how to use the second procedure, the function for calculating the column of the last non-blank cell in a row using the Find method.
The Code
Option Explicit
Sub LastColumnSuptileDifferences()
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
Dim ws As Worksheet
Set ws = wb.Worksheets("Sheet1")
' Cell Value Comment
' A1: 1 Value
' B1: ="" Formula
' C1 1 Value: Hidden Column
' D1: Fill Color
Debug.Print ws.Rows(1).Find("*", , xlFormulas, , , xlPrevious).Column ' 3
Debug.Print ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column ' 2
Debug.Print ws.Rows(1).Find("*", , xlValues, , , xlPrevious).Column ' 1
Debug.Print ws.Rows(1).CurrentRegion.Columns.Count ' 3
Debug.Print ws.Rows(1).SpecialCells(xlCellTypeLastCell).Column ' 4
Debug.Print ws.UsedRange.Rows(1).Columns.Count ' 4
End Sub
' This will find the last column even if columns are hidden
' unless you set 'excludeEmpties' to 'True'.
' If you set 'excludeEmpties' to 'True', the right-most cells in the row,
' possibly containing a formula that evaluates to "", will be skipped.
' Additionally only the visible cells will be included, i.e. hidden
' right-most columns, possibly containing data in cells of the row,
' will not be considered (mimicking 'End(xlToLeft)' or CRTL+Left).
Function getLastColumnInRow(RowNumber As Variant, _
Optional Sheet As Worksheet = Nothing, _
Optional excludeEmpties As Boolean = False)
If Sheet Is Nothing Then
Set Sheet = ActiveSheet
End If
Dim FormVal As XlFindLookIn
If excludeEmpties Then
FormVal = xlValues
Else
FormVal = xlFormulas
End If
Dim rng As Range
Set rng = Sheet.Rows(RowNumber).Find(What:="*", _
LookIn:=FormVal, _
SearchDirection:=xlPrevious)
If Not rng Is Nothing Then
getLastColumnInRow = rng.Column
Else
getLastColumnInRow = 0
End If
End Function
Sub testgetLastColumnInRow()
'...
LastColumn1 = getLastColumnInRow(5, wsDestination)
If LastColumn1 = 0 Then
MsgBox "No Data.", vbExclamation, "Empty Row"
Exit Sub ' or whatever
End If
' Continue with code.
Debug.Print LastColumn1
'...
End Sub
So you didn't quite get the last column right. Here's it back.
Dim Cell As Range, cRange As Range, lrw As Long
Dim wsDestination As Worksheet, wsSource As Worksheet
'set worksheets
With ThisWorkbook
Set wsSource = .Worksheets(Sheets.Count)
Set wsDestination = .Worksheets("Overview")
End With
LastRow1 = wsSource.Cells(Rows.Count, "H").End(xlUp).Row
LastColumn1 = wsDestination.Cells(5, columns.count).End(xltoleft).Column
Set cRange = wsSource.Range(wsSource.Cells(1, 8), wsSource.Cells(LastRow1, 8))
For Each Cell In cRange.Cells
If Cell.Value > 0 Then wsDestination.Cells(Cell.Row, LastColumn1).offset(3, 1) = Cell.Value
Next Cell
End Sub```

How to copy an entire row to another sheet if a cell = true

I have 2 sheets, 'Initial' & 'Report1'. I'm trying to copy specific rows from 'Inital' to 'Report1' when the cell in column 'H' is = "On going".
I have the function as a button in excel but cant workout how to copy and paste the line and move onto the next cell.
Also, Column D is formula and needs to be pasted special to copy over.
I have attached the current code I have tried but it errors. Any help would be greatly appreciated.
Sub GenRep1_Click()
Dim Inti As Worksheet
Dim rep1 As Worksheet
Set Inti = ThisWorkbook.Worksheets("Inital")
Set rep1 = ThisWorkbook.Worksheets("Report1")
Dim rngA As Range
Dim cell As Range
Set rngA = Sheets("Inti").Range("H5:H9999")
For Each cell In rngA
If cell.Value = "On going" Then
cell.EntireRow.Copy
Sheets("Inti").Range("").End(xlDown).Select
ActiveSheet.Paste
End If
Next cell
End Sub
I expect the all rows in column 'H' that = "On Going" to be copied to "Report1".
I think this does what you want. You might want to improve the range you're looping through in case you only have, e.g. 100 cells of data.
A quicker approach than looping would be AutoFilter.
Sub GenRep1_Click()
Dim Inti As Worksheet
Dim rep1 As Worksheet
Set Inti = ThisWorkbook.Worksheets("Inital") 'check name - typo?
Set rep1 = ThisWorkbook.Worksheets("Report1")
Dim rngA As Range
Dim cell As Range
Set rngA = Inti.Range("H5:H9999") 'already defined worksheet so just use variable
'Set rngA = Inti.Range("H5",inti.range("H" & rows.count).end(xlup)) 'would be more efficient
For Each cell In rngA
If cell.Value = "On going" Then
cell.EntireRow.Copy
repl.Range("A" & Rows.Count).End(xlUp)(2).PasteSpecial xlValues 'copy to the other sheet
End If
Next cell
End Sub

Transferring rows into another sheet

I am trying to transfer two rows of Sheet1 (randomly and based on certain criteria) into Sheet3.
The values in cells "P2" and "P5" indicate the row number to be transferred, and column "A" has row numbers.
There's no possibility that values in "P2" and "P5" could match multiple rows in column "A". They should match 1 row each, so only one row should be copied per "P2" and "P5". Yet, sometimes I see multiple rows getting copied.
Below is the code:
Sub copyrows()
Dim tfRow As Range, cell As Object
Set tfRow = Range("A1:A") 'Range which includes the values
For Each cell In tfRow
If IsEmpty(cell) Then
Exit Sub
End If
If cell.Value = Range("P2").Value Then
cell.EntireRow.Copy
Sheet3.Select 'Target sheet
ActiveSheet.Range("A65536").End(xlUp).Select
Selection.Offset(1, 0).Select
ActiveSheet.Paste
End If
Next
End Sub
Sub copyrows2()
Dim tfRow2 As Range, cell As Object
Set tfRow2 = Range("A1:A") 'Range which includes the values
For Each cell In tfRow2
If IsEmpty(cell) Then
Exit Sub
End If
If cell.Value = Range("P5").Value Then
cell.EntireRow.Copy
Sheet3.Select 'Target sheet
ActiveSheet.Range("A65536").End(xlUp).Select
Selection.Offset(1, 0).Select
ActiveSheet.Paste
End If
Next
End Sub
As #urdearboy mentioned in the commnets above, you need to add a row to your second A column range to avoid getting the error.
To merge two conditions, in your case add an Or to your If.
To run the code faster, don't Select and Activate different sheets, it takes a long time for the code to run. Instead, use a Range object, like CopyRng and every time the if criteria is ok, you add that cell to the range using the Union function.
Read HERE about the Union functionality.
More comments inside the code's notes below.
Modified Code
Option Explicit
Sub copyrows()
Dim Sht1 As Worksheet, Sht3 As Worksheet
Dim tfRow As Range, C As Range ' use Range not Object, also try not to use Cell it's close to Cells
Dim CopyRng As Range
Dim LastRow As Long
Set Sht1 = Sheet1
Set Sht3 = Sheet3
With Sht1
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row ' get last row with data in column A
Set tfRow = .Range("A1:A" & LastRow) 'Range which includes the values
For Each C In tfRow
If IsEmpty(C) Then
Exit Sub
End If
If C.Value = .Range("P2").Value Or C.Value = .Range("P5").Value Then ' use Or to combine both scenarios
If Not CopyRng Is Nothing Then
Set CopyRng = Application.Union(CopyRng, C) ' use Union to merge multiple ranges
Else
Set CopyRng = C
End If
End If
Next C
End With
' make sure there is at least one cells in your merged range
If Not CopyRng Is Nothing Then
' get last row with data in "sheet3"
LastRow = Sht3.Cells(Sht3.Rows.Count, "A").End(xlUp).Row
CopyRng.EntireRow.Copy Destination:=Sht3.Range("A" & LastRow + 1)
End If
End Sub

Resources