Range column use variable (VBA Macro) - vba

i have a code like this :
Dim lastRow As Long
Dim i As Integer
Dim inrange As Range
lRow = Sheet12.Cells.SpecialCells(xlLastCell).Row
Do While Application.CountA(Sheet12.Rows(lRow)) = 0 And lRow <> 1
lRow = lRow - 1
Loop
lastRow = lRow + 1
For l = 1 To 31
inrange = Range("A" & lastRow & " , E" & lastRow)** 'when i tried this code error
Sheet12.Cells(lastRow, l).Interior.Color = RGB(255, 255, 0)
inrange.Borders(xlEdgeLeft).LineStyle = xlContinuous
inrange.Borders(xlEdgeTop).LineStyle = xlContinuous
inrange.Borders(xlEdgeRight).LineStyle = xlContinuous
inrange.Borders(xlEdgeBottom).LineStyle = xlContinuous
Next
the error message is "object variable or with block variable not set", so what should i do. thank's for help.

You need to use the keyword set when assigning a range to a variable. Also I modified your code a little bit I think this is what you are trying to accomplish.
Sub Test()
Dim inrange As Range
Dim lastRow As Long
Dim i As Long
With Sheet12
' Get the last row.
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
For i = 1 To 31
' Use the keywprd Set before asigning to an object variable
' like a range, worksheet, workbook.
Set inrange = .Range("A" & lastRow & " , E" & lastRow) 'when i tried this code error
inrange.Interior.Color = RGB(255, 255, 0)
inrange.BorderAround xlContinuous
lastRow = lastRow + 1
Next
End With
End Sub
Thanks, I hope this helps :)

Related

VBA Combine columns stack in the loop

I have the issue with stacking in the loop
The macro should combine all columns (changeable number of rows) into one column.
Sub CombineColumns()
Dim xRng As Range
Dim i As Integer
Dim xLastRow As Integer
On Error Resume Next
Set xRng = Application.Range("A1", Range("A1").End(xlDown).End(xlToRight))
xLastRow = xRng.Columns(1).Rows.Count + 1
For i = 2 To xRng.Columns.Count
Range(xRng.Cells(1, i), xRng.Cells(xRng.Columns(i).Rows.Count, i)).Cut
ActiveSheet.Paste Destination:=xRng.Cells(xLastRow, 1)
xLastRow = xLastRow + xRng.Columns(i).Rows.Count
Next
End Sub
Using Array is simple and fast.
Sub test()
Dim Ws As Worksheet, toWS As Worksheet
Dim vDB, vR()
Dim i As Long, j As Integer, n As Long
Set Ws = ActiveSheet
vDB = Ws.UsedRange
r = UBound(vDB, 1)
c = UBound(vDB, 2)
For i = 1 To r
For j = 1 To c
n = n + 1
ReDim Preserve vR(1 To n)
vR(n) = vDB(i, j)
Next j
Next i
Set toWS = Sheets.Add ' set toWs = Sheets(2) ~~> set your sheet
With toWS
.Cells.Clear
.Range("a1").Resize(n) = WorksheetFunction.Transpose(vR)
End With
End Sub
If I got you right you want to do sth. like that
Option Explicit
Sub CombineColumns()
Dim xRng As Range
Dim i As Long
Dim xLastRow As Long
'On Error Resume Next
Set xRng = Application.Range("A1", Range("A1").End(xlToRight))
xLastRow = lastRow(1) + 1
For i = 2 To xRng.Columns.Count
Range(xRng.Cells(1, i), xRng.Cells(lastRow(i), i)).Cut
ActiveSheet.Paste Destination:=xRng.Cells(xLastRow, 1)
xLastRow = lastRow(1) + 1
Next
End Sub
Function lastRow(col As Long, Optional wks As Worksheet) As Long
If wks Is Nothing Then
Set wks = ActiveSheet
End If
lastRow = wks.Cells(wks.Rows.Count, col).End(xlUp).Row
End Function
The code still needs some improvement as it might loop over all columns espeically if there is no data.
This assumes on all your columns you have data on the 2nd row, to correctly identify the last column.
Option Explicit
Public Sub CombineColumns()
Dim LastColumn As Long, LastRow As Long, LastRowA As Long, i As Long, RngAddress As String
With ActiveSheet
' This assumes you have data on row 2 on all columns
LastColumn = .Cells(2, .Columns.Count).End(xlToLeft).Column
For i = 2 To LastColumn
' Get the last row of Col A on each iteration
LastRowA = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
' Get last row of the Col we're checking
LastRow = .Cells(.Rows.Count, i).End(xlUp).Row
' Get the used range address of the current Col
RngAddress = .Range(.Cells(1, i), Cells(LastRow, i)).Address
' Check if we have blank cells among the rows of the current Col
.Range(.Cells(1, i), Cells(LastRow, i)).Value2 = Evaluate("IF(NOT(ISBLANK(" & RngAddress & "))," & RngAddress & ")")
' Compress data (if there's no empty cells in the current Col the below line will give error, that's the role of err handling)
On Error Resume Next
.Range(.Cells(1, i), Cells(LastRow, i)).SpecialCells(xlCellTypeConstants, 4).Delete xlShiftUp
On Error GoTo 0
' Update the last row in case we compressed data
LastRow = .Cells(.Rows.Count, i).End(xlUp).Row
' Paste data in Col A
.Range(.Cells(1, i), Cells(LastRow, i)).Cut Destination:=.Range("A" & LastRowA)
Next i
Application.CutCopyMode = False
End With
End Sub
Maybe this could be a convenient solution for you :
Sub CombineColumns()
Dim LastRow As Long
LastRow = ActiveSheet.UsedRange.Rows(ActiveSheet.UsedRange.Rows.Count).Row
Range("A2:A" & LastRow).Formula = "=B2 & C2 & D2 & E2 & F2 & G2 & H2" 'Insert here the columns you need to be combined
End Sub
Let me know if changes are necessary.

Compare 2 excel file using macro

I was just wondering if is there any way of comparing two excels spreadsheets using macro. I have a piece of macro that basically does the work but it checks column by column. So say in case I have a value defined in A(1,1) in sheet1 and if the same value is not present in A(1,1) in sheet2 but the value present in any row of the column then it won't raise a complaint.
'compare Sheet
Sub CompareTable()
Dim tem, tem1 As String
Dim text1, text2 As String
Dim i As Integer, hang1 As Long, hang2 As Long, lie As Long, maxhang As Long, maxlie As Long
Sheets("Sheet1").Select
Columns("A:A").Select
With Selection.Interior
.Pattern = xlNone
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Range("A1").Select
Sheets("Sheet2").Select
Dim lastRow As Long
With ActiveSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Rows("1:" & lastRow).Select
With Selection.Interior
.Pattern = xlNone
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Range("A1").Select
maxhang = lastRow ' number of the last row containg data
MaxRow = lastRow
Dim LastCol As Integer
With ActiveSheet
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
MaxColumn = LastCol
For col = 1 To MaxColumn
For hang1 = 2 To maxhang
Dim a As Integer
a = 0
tem = Sheets(1).Cells(hang1, col)
For hang2 = 1 To maxhang
tem1 = Sheets(2).Cells(hang2, col)
If tem1 = tem Then
a = 1
Sheets(2).Cells(hang2, col).Interior.ColorIndex = 6
For lie = 1 To maxlie
text1 = Sheets(1).Cells(hang1, lie)
text2 = Sheets(2).Cells(hang2, lie)
If text1 <> text2 Then
Sheets(2).Cells(hang2, lie).Interior.ColorIndex = 8
End If
Next
End If
Next
If a = 0 Then
Sheets(1).Cells(hang1, 1).Interior.ColorIndex = 5
End If
Next
Next
End Sub
Note : I'm looking for any solution that could give me a row match, so if any value of the given row is not matched with the sheet2 then it should highlight it.
I'm open to have any other alternative as well. Any help or suggestion would be much appreciated.
Thanks for your time !
Im not sure if this is what you are expecting. Please see my below code
Sub CompareTable()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim table1 As Range
Dim table2 As Range
Dim table1Rows As Integer
Dim table1Cols As Integer
Set ws1 = Worksheets("sheet1")
Set ws2 = Worksheets("sheet2")
Set table1 = ws1.Cells
Set table2 = ws2.Cells
table1Rows = ws1.UsedRange.Rows.Count
table1Cols = ws1.UsedRange.Columns.Count
For i = 1 To table1Rows
For j = 1 To table1Cols
If table1(i, j).Value = table2(i, j).Value Then
Else
ws1.Cells(i, j).Interior.Color = vbYellow
End If
Next
Next
End Sub
Sheet1 table
Sheet2 table
After Running the code tgisis my result

Comparing value of cells from two different sheets

First my code:
Option Explicit
Sub UpdateCandidates()
Application.ScreenUpdating = False
Dim wks As Worksheet, wks2 As Worksheet
Dim Lastrow As String, Lastrow2 As String
Dim Rng As Range, i As Long, Rng2 As Range, i2 As Long
Dim cell As Variant, cell2 As Variant
Set wks = ThisWorkbook.Worksheets("Candidates")
Lastrow = wks.Range("B" & Rows.Count).End(xlUp).Row
If Lastrow > 1 Then
cell = wks.Range("B2:B" & Lastrow).Value
i = 1: Set Rng = Nothing
While i <= Lastrow
For i = i To Lastrow
Set wks2 = ThisWorkbook.Worksheets("Job live")
Lastrow2 = wks2.Range("A" & Rows.Count).End(xlUp).Row
If Lastrow2 > 1 Then
cell2 = wks2.Range("A2:A" & Lastrow2).Value
i2 = 1: Set Rng2 = Nothing
While i2 <= Lastrow2
For i2 = i2 To Lastrow2
If cell = cell2(i2, 1) Then
MsgBox ("found")
End If
Next
Wend
End If
Next
Wend
End If
Application.ScreenUpdating = True
End Sub
This basically works and compares the two columns but at the end it shows an error:
"Subscript out of range"
I don't understand why. I thought it's because of <= Lastrow but fixing to < Lastrow doesn't change anything.
I also would like to copy a value from the first sheet to the second one to a particular cell. And also insert a row below the cell from my second sheet.
I also don't understand why I have to compare cell to cell2(i2,1) and not cell to cell2. If I compare cell to cell2 it says type mismatch. And I have the same error if I enter a second value in my sheets.
What's wrong with my code?
I see your code, and here's a proposal
Option Explicit
Sub CompareDefinedRanges()
Dim rng1, rng2 As Range
Dim found As Boolean
Dim i, j, foundAt As Integer
Set rng1 = Worksheets("Candidates").Range("B2", Worksheets("candidates").Range("B2").End(xlDown).Address)
Set rng2 = Worksheets("Job live").Range("A2", Worksheets("Job Live").Range("A2").End(xlDown).Address)
'show items
For i = 1 To rng1.Rows.Count
found = False
foundAt = 0
For j = 1 To rng2.Rows.Count
If rng1.Item(i) = rng2.Item(j) Then
found = True
foundAt = j
End If
Next j
If found Then
MsgBox rng1.Item(i).Value & " found at " & CStr(foundAt), , "Candidates"
Else
MsgBox rng1.Item(i).Value & " not found", , "Candidates"
End If
Next i
Set rng1 = Nothing
Set rng2 = Nothing
End Sub

Check Each Value In Range On Last Row [VBA]

I've got a sheet set up to get the contents of the last row. I want to check the values on that last row from J to W. I want to check if all the values are "YES" and if so return an OK into a variable. Here is what I have so far, it should be clear from the below what I am trying to do:
lastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
sName = ActiveSheet.Name
For Each c In Worksheets(sName).Range(Cells(J, lastRow), Cells(W, lastRow))
If c.Value = "YES" Then
vData = "OK"
Else
vData = "Error."
End If
Next c
Thanks.
Cells(x,y) takes two integers as arguments, and it's row, column not column, row!
Try
For Each c In Sheets(sName).Range(Cells(lastRow, 10), Cells(lastRow, 23))
Dim lRow As Long
Dim lCol As Long
Dim ws As Excel.Worksheet
Set ws = Application.ActiveSheet
lRow = ws.UsedRange.Rows.count
lCol = 10
Do While lCol <= 21
If ws.Cells(lRow, lCol).Value <> "YES" Then
vData = "Error."
Exit Sub
End If
lCol = lCol + 1
Loop
Try this one:
Public Sub checking()
Dim lastRow As Long
'Here, I take row count by using column "J"
'You can modify it if you need
lastRow = Sheets("sheetname").Range("J" & Rows.Count).End(xlUp).row
For Each cell In Sheets("sheetname").Range("J" & lastRow & ":W" & lastRow)
If cell.Value = "YES" Then
vData = "OK"
Else
vData = "Error."
Exit For
End If
Next cell
'Show result
MsgBox vData
End Sub

copy only one column if criteria is met (Need to adjust my existing code)

The below code works great for copying an entire row, how do I make it so I only copy over the first column.
I have tried altering range with no success? Condition is in J, the only column to copy should be 1st one.
Dim cell As Range
Dim lastRow As Long, i As Long
lastRow = Range("B" & Rows.Count).End(xlUp).Row
i = 1
For Each cell In Sheets(1).Range("J1:J" & lastRow)
If cell.Value = 1 Then
cell.EntireRow.Copy Sheets(5).Cells(i, 1)
i = i + 1
End If
Next
End Sub
Many thanks!
try
Dim cell As Range
Dim lastRow As Long, i As Long
lastRow = Range("B" & Rows.Count).End(xlUp).Row
i = 1
For Each cell In Sheets(1).Range("J1:J" & lastRow)
If cell.Value = 1 Then
cells(cell.row,1).Copy Sheets(5).Cells(i, 1)
i = i + 1
End If
Next
End Sub
Dim cell As Range
Dim lastRow As Long, i As Long
lastRow = Range("B" & Rows.Count).End(xlUp).Row
i = 1
For Each cell In Sheets(1).Range("J1:J" & lastRow)
If cell.Value = 1 Then
cell.End(xlToLeft).Copy Sheets(5).Cells(i, 1)
i = i + 1
End If
Next
End Sub
Just switch EntireRow to EntireColumn, it is as simple as that! ;)
Dim rCell As Range
Dim lastRow As Long, i As Long
lastRow = Range("B" & Rows.Count).End(xlUp).Row
i = 1
For Each rCell In Sheets(1).Range("J1:J" & lastRow)
If rcell.Value = 1 Then
rcell.EntireColumn.Copy Sheets(5).Cells(1, i)
i = i + 1
End If
Next rCell