Excel VBA on Range Error - Quick Fix? - vba

The below code gives an error but when I change the range to .Range(A2:A9999) it works...
But it's ugly. Is there way to grab all the data in column(A) from A2 and down? and copy that into B2?
Sheets("AA").Range("A2:A").Value = Sheets("BB").Range("B2:B").Value

To have it in one line you can do it as follows:
Sheets("AA").Range("A2", Cells(Rows.Count, "A")).Copy Sheets("BB").Range("B2")
By the way, it copies everything, not only values but also formatting. To run it your sheet AA should be active one.

Sub CopyValues()
Dim rValues As Range
With Sheet1
Set rValues = .Range("A2", .Cells(.Rows.Count, 1).End(xlUp))
End With
rValues.Offset(, 1).Value = rValues.Value
End Sub

By finding the last populated cell in column A, you can be more precise in what you are copying.
This copies the contents of column A on the src sheet to column B of the tgt sheet:
Sub CopyOneColumnToAnother()
Dim wb As Workbook
Dim src As Worksheet
Dim tgt As Worksheet
Dim lastRow As Long
Set wb = ThisWorkbook
Set src = wb.Sheets("Sheet5")
Set tgt = wb.Sheets("Sheet6")
lastRow = src.Range("A" & src.Rows.Count).End(xlUp).Row
tgt.Range("B2:B" & lastRow).Value = src.Range("A2:A" & lastRow).Value
End Sub
The reason you are getting the error is because your ranges don't have valid end points. Range ([firstcell]:[lastcell]) is the correct syntax, so you need to add a row for the lastcell in both your source and target ranges.
Note that even if your code runs, it won't do want you want. You are setting column A to equal column B. You need to flip the left and right-hand sides of your statement.

Why not just copy the whole column and re-insert whatever was in B1:
Range("A:A").Copy Columns("B:B")
Range("B1").Value = "Whatever"
In more detail:
Dim previous 'As Variant (or whatever it is)
previous = Worksheets("BB").Range("B1").Value
Worksheets("AA").Range("A:A").Copy Worksheets("BB").Columns("B:B")
Worksheets("BB").Range("B1").Value = previous
Unless there is data further down in column B which you wish to keep (you haven't stated).

Related

Write on the next available cell of a given column

I have a somewhat simple macro that I have made but I am rusty as I have not coded in a few years. As simply as I can put it, I Have two different Workbooks. If the workbook I have open has a certain value (or no value), I want it to fill the other workbook("Test Template") with either "proposal or pre-proposal."
That has all been easy for me. But since the worksheet adds rows as we input data, I need it to fill those values in the next available row.
I will attach code but don't worry about the proposal stuff, I just need the range changed from a specific cell into the next available cell in the column. (if d28 is full, put in d29).
Public Sub foo()
Dim x As Workbook
Dim y As Workbook
'## Open both workbooks first:
Set x = ActiveWorkbook
Set y = Workbooks.Open("C:\Users\hmaggio\Desktop\Test Template.xlsx")
'copy Names from x(active):
x.Sheets("Sheet1").Range("C4").Copy
'paste to y worksheet(template):
y.Sheets("Sheet1").Range("B28").PasteSpecial
If x.Sheets("Sheet1").Range("C15") = "" Then
y.Sheets("Sheet1").Range("D28").Value = "proposal"
Else
y.Sheets("Sheet1").Range("D28").Value = "preproposal"
End If
First, you need a variable where you'll store the last used row number:
dim lngRows as long
lngRows = Cells(Rows.Count, "D").End(xlUp).Row
Then replace your lines of code where you have .Range("B28") with either .Cells(lngRows+1,2) or .Range("B"&lngRows)
The object Range offers a method called End that returns the last range on a certain direction.
Range("A1").End(xlDown) '<-- returns the last non-empty range going down from cell A1
Range("A1").End(xlUp) '<-- same, but going up
Range("A1").End(xlToRight) '<-- same, but going right
Range("A2").End(xlToLeft) '<-- same, but going left
In your case, hence, you can detect and use the last row of column B like this:
nextRow = y.Sheets("Sheet1").Range("B3").End(xlDown).Row + 1
More details:
The first Range of your column B is the header Range("B3")
You get the last filled range going down with .End(xlDown)
Specifically, you get the Row of that range
You add + 1 (cause you want the next available row
You store the row in the variable nextRow
... that you can then use like this:
y.Sheets("Sheet1").Range("B" & nextRow ).PasteSpecial
Try this
Public Sub foo()
Dim x As Workbook
Dim y As Workbook
Dim fromWs As Worksheet
Dim toWs As Worksheet
Dim Target As Range
'## Open both workbooks first:
Set x = ActiveWorkbook
Set y = Workbooks.Open("C:\Users\hmaggio\Desktop\Test Template.xlsx")
Set fromWs = x.Sheets("Sheet1")
Set toWs = y.Sheets("Sheet1")
With fromWs
Set Target = toWs.Range("b" & Rows.Count).End(xlUp)(2) '<~~next row Column B cell
Target = .Range("c4") 'Column B
If .Range("c15") = "" Then
Target.Offset(, 2) = "proposal" 'Column D
Else
Target.Offset(, 2) = "preproposal"
End If
End With
End Sub

if else statement at copying and pasting a cell value

I have the following code which will copy/paste some columns from "data" worksheet and pastes to the next empty column in to the column that i specify in the mastersheet called "KomKo".
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("data")
Set pasteSheet = Worksheets("KoMKo")
lRow = copySheet.Cells(copySheet.Rows.Count, 1).End(xlUp).Row
With copySheet.Range("BX2:BX" & lRow)
pasteSheet.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).Resize(.Rows.Count, .Columns.Count) = .Value
End With
Now i would like to add an if condition for another column; which should say "if column U in Worksheet "data" has cell value "8636" then these values should be pasted to Column H in Worksheet "KomKo"(pastesheet); to the next row as i used the code above in the "with" part.
Else( If the value in Column H is not 8636) then it should paste the value inside this column to Column G at Worksheet "KomKo"(pastesheet) with same preferences as above again.
How can i do this ?
So, I've come up with a suggestion below using an if-then within a loop. I think it's close to what you want...
Sub try6()
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim x As Range
Set ws = Worksheets("data")
Set ws2 = Worksheets("KomKo")
For Each x In ws.Range("C1:C100")
If x.Value = 8636 Then
ws2.Range("H:H").Value = ws.Cells(Rows.Count, "A").Value
ElseIf x <> 8636 Then
ws2.Range("G:G").Value = ws.Range(Rows.Count, "B").Value
End If
Next x
End Sub
Testing it, it took a while to execute. I'd say, set a dynamic range at something like A10000 and copy it directly without needing to necessarily test for whether there is a value in the range being copied.
You can also use the Select method for the purpose and copy the selection - from personal experience, I've had mixed success with it and I've seen people advise against using it here.
These are my .02, hope it helps! Cheers.

Pointing to a cell address given in string format

I have cell addresses given in an excel sheet and wanted to print a specific formula in other excel sheet referring to the cell addresses given in the previous sheet. Please suggest vba function for this. The cell addresses are in string format so corresponding row no. and col. no need to be extracted from the string. Is there an existing function for this in vba?
I'm not sure I understand correctly, but the Range method accepts string input. For your example, this would work:
Worksheets("Sheet2").Range(Worksheets("Sheet1").Range("A1").Value)=Worksheets("Sheet1").Range("A2").Value
Same code, a bit easier on the eyes:
Dim strLocation As String
strLocation = Worksheets("Sheet1").Range("A1").Value
Worksheets("Sheet2").Range(strLocation) = Worksheets("Sheet1").Range("A2").Value
Is this what you are looking to do? Do you need more help understanding it?
Below code will check for last row in sheet1 column A and try to get values present in odd rows in column A and print the result in even row numbers
Sub testt1()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = Worksheets("sheet1")
Set ws2 = Worksheets("sheet2")
Dim lastRow As Long
lastRow = ws1.Range("A" & Rows.Count).End(xlUp).Row
On Error Resume Next
For i = 1 To lastRow
t1 = ws1.Cells(i, 1).Value
t2 = ws2.Range(t1).Value
ws1.Cells(i + 1, 1).Value = t2
i = i + 1
Next
End Sub

Copied range searches for next empty cell in a row but skips merged cells

I've seen a lot of people talking about this problem but more from a point of view of copying merged cells into single cells. I have a procedure that gets a range from a workbook, opens the second workbook and attempts to paste it into the next blank cell in the specified row;
Public Sub BankBalances()
Dim fname As String
Dim fname2 As String
Dim mt As String, yr As String
'get the selected month
mt = MonthBox.Value
'get the selected year
yr = YearBox.Value
'set the file path to the selected year, month and the saving format
fname = yr & mt & "DB" & ".xlsx"
'set the file path to the selected year, month to open the trial balance sheet
fname2 = yr & mt & "TB" & ".xlsx"
'get the ranges
Dim rng1 As Range
Dim rng2 As Range
Set rng1 = Workbooks(fname2).Worksheets("excel").Range("I100")
'check for the next empty cell in row 55
Set rng2 = Workbooks(fname).Worksheets("UK monthly dashboard").Cells(55, Columns.Count).End(xlToLeft).Offset(0, 1)
'set the new range to hold the data from the original range
rng2.Value = rng1.Value
'set the result to format according to the other information in the workbook
rng2.Value = Round(rng1.Value / 1000, 0)
End Sub
The above code will paste the data in the next blank cell in the row that is not merged. I need it to be able to paste into the merged cells.
What I want to know is if there is a way using VBA to put the data into the merged cell or if I will need to do a separate procedure to check for merged cells, unmerge them and then merge them once the data has copied across.
If that is the way, would I be able to do that in a similar way to checking for the next empty cell, then check if it's merged, then carry out the unmerge and merge again.
If I understand what you are saying then yes, but if I may alter your example I want the contents of say A1 put into D1:D2 that are merged. So its a value of one cell going into two merged together – JamesDev 4 hours ago
Is this what you are trying?
Sub Sample()
Dim Rng1 As Range
Dim Rng2 As Range
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
Set Rng1 = .Range("A1")
Set Rng2 = .Range("D1:D2")
'~~> Check if cells are merged
If Rng2.MergeCells Then
'~~> If merged then write to first cell
Rng2.Cells(1, 1).Value = Rng1.Value
Else
Rng2.Value = Rng1.Value
End If
End With
End Sub

Loop paste formula until next cell in range is empty

I am trying to paste a formula next to range of cells, but only the one's that contains a value, the script must loop until the next cell in the range is empty. For instance Sheet 1 Column A contains date until row 12, then I would like to paste a formula in column D2:D12 Regards
Like this?
Option Explicit
Sub Sample()
Dim lastRow As Long, i As Long
Dim ws As Worksheet
Set ws = Sheets("Sheet1")
lastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
With ws
For i = 1 To lastRow
If Len(Trim(.Range("A" & i).Value)) <> 0 Then _
.Range("D" & i).Formula = "YOUR FORMULA"
Next i
End With
End Sub
As you are looking down to the first blank cell then you can avoid a loop and use
The code includes a test to make sure that the code doesn't proceed if all of column A is blank - ie if the range from A1 down extends to the bottom of the sheet and A1 is blank
This code adds a sample formula linking each cell in column D to the respective row in column B
Sub FillData()
Dim rng1 As Range
Set rng1 = Range([a1], [a1].End(xlDown))
If Not (rng1.Rows.Count = Rows.Count And Len([a1].Value) = 0) Then rng1.Offset(0, 3).FormulaR1C1 = "=RC2"
End Sub
I like Sid's beginning, but once you have the range of rows, you can insert the formula into column D all at once, without looping, several ways, here's one:
Option Explicit
Sub AddFormula()
Dim LR As Long
LR = Range("A" & Row.Count).End(xlUp).Row
Range("D2:D12").Formula = "=A2 + 7" 'just an example of a formula
End Sub
Try this:
Range("A:A").SpecialCells(2).Areas(1).Offset(, 3).Formula = "MyFormula"
This is a simple solution that is built into Excel, as long as you don't want to copy to the first blank, jump over the blank, then continue copying:
Enter the formula in the first cell of your range, and as long as it is in the column directly to the right or left of your range of filled cells, simply double-click the black box handler in the bottom right-hand corner of the cell. That will automatically copy your formula down to the last non-empty cell of the range.