I have a piece of VBA code that is taking data from a spread sheet and formatting it into an input file. This code loops through each column header to makes sure it can find the column its looking for and then offsets by one to get off of the header row and then copies the data to another template.
However this sheet is used by multiple users and the amount of rows being populated can vary so I have set up a variable called rowcount. In this example I'm working on I have 5 records and so I'm trying to select the range from the active cell to the rowcount value (5) but I'm just stuck on the following line:
ActiveSheet.Range(ActiveCell, RowCount).Select
Below is the full code for this section, I know what I'm doing is wrong but any searching via Google throws up results that are too specific and I can't tweak the code to work for me.
If ActiveCell.Value = "Account Name" Then
ActiveCell.Offset(1, 0).Select
If ActiveCell.Value <> "" Then
ActiveSheet.Range(ActiveCell, RowCount).Select
Selection.Copy
Sheets("Input").Activate
ActiveSheet.Range("C2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Worksheets("Account Details").Select
End If
End If
For someone with more VBA knowledge I'm sure its easy but I'm essentially trying to get highlight Activecell and down to the variable so in this case A5:A10, copy, then paste.
Thanks in advance
Using Select, Activate and ActiveCell is not considered a good practice in VBA. See How to avoid using Select in Excel VBA
However, it takes time to learn to avoid these. Thus, in your code change this line:
ActiveSheet.Range(ActiveCell, RowCount).Select
To this one:
ActiveSheet.Range(ActiveCell, Cells(Rows.Count, ActiveCell.Column)).Select
And if you have rowCount declared and set correctly, then this is a possible option:
Dim rowCount As Long: rowCount = 5
ActiveSheet.Range(ActiveCell.Column, rowCount).Select
First yours,
If ActiveCell.Value = "Account Name" Then
ActiveCell.Offset(1, 0).Select
If ActiveCell.Value <> "" Then
ActiveCell.RESIZE(RowCount, 1).Select '<~~ resize to the # of rows
Selection.Copy
Sheets("Input").Activate
ActiveSheet.Range("C2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Worksheets("Account Details").Select
End If
End If
Now without Select, Activate or ActiveCell
dim c as variant
with worksheets("sheet1") 'you should know what worksheet you are starting out on
c = application.match("Account Name", .rows(4), 0)
if not iserror(c) then
if .cells(5, c).Value <> "" then
workSheets("Input").Range("C2").resize(RowCount, 1) = _
.cells(5, c).resize(RowCount, 1).value
end if
end if
end with
How to avoid using Select in Excel VBA
Or just use:
ActiveCell.Resize(RowCount,1).Select
Where 1 is number of columns.
At the moment in your range you have just the activecell and row number.
Try something like this:
ActiveSheet.Range(activecell.address &":" &cells(RowCount,ActiveCell.Column).address).select
Don't select the range to copy it; implementing something like this should do the job for you:
Sub Test()
Dim RNG As Range
If ActiveCell.Value = "Account Name" Then
With ActiveSheet
Set RNG = .Range(.Cells(ActiveCell.Row + 1, ActiveCell.Column), ActiveSheet.Cells(.Cells(ActiveSheet.Rows.Count, ActiveCell.Column).End(xlUp).Row, ActiveCell.Column))
End With
RNG.Copy Sheets("Input").Range("C2")
End If
End Sub
Related
I am new to VBA and i tried to create i sub that will update (with vlookup and then copy paste) the comments with new comments from another sheet depending on the case status ("Open"). Basically i tried to put together a code that inserts new rows at the end of the table with a vlookup macro.
The main problem is that i do not know how to instruct excel to identify in which cell he should do the lookup and then copy and paste. As in the example below "M528" will not do it as i want to keep the records that are closed as well. I receive daily only the open cases so therefore i don`t want the code to do any vlookups in those cells where the status is "Closed"
Sub ChangesUpdates()
lastRow = Worksheets("CurrentDash").Range("A" & Rows.Count).End(xlUp).Row
For r = 2 To lastRow
If Worksheets("CurrentDash").Range("AS" & r).Value = "Open" Then
Range("M528").Select
Application.CutCopyMode = False
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = _
"=VLOOKUP([#[Parent Case Number]],NewData!C[-12]:C,13,0)"
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Without changing things too much, you can do most of what you want with
Sub ChangesUpdates()
lastRow = Worksheets("CurrentDash").Range("A" & Rows.Count).End(xlUp).Row
For rw = 2 To lastRow
If Worksheets("CurrentDash").Range("AS" & rw).Value = "Open" Then
With Worksheets("CurrentDash").Range("M" & rw)
.FormulaR1C1 = "=VLOOKUP([#[Parent Case Number]],NewData!C[-12]:C,13,0)"
.Value = .Value ' effectively a paste-values
End With
End If
Next rw
End Sub
There's no cell selection/activation here so the screen won't move to the updates, but it should cycle through the same set as your routine.
There's some remaining question in my mind about how stable the lookup area is, which you should think about.
I have a problem with the autofill function. I want to use the macro to fill in the date until there is nothing left in B. The problem is that there are some gaps there. Can I change the code so that it fills up to the last line in B. I tried it with the code below. However, it does not work.
Sub fill()
Sheets("Table1").Select
Columns("C:C").Select
Selection.Insert Shift:=xlToRight
Range("C2").Select
ActiveCell.FormulaR1C1 = "=IF(RC[-1]="""",R[-1]C,RC[-1])"
ActiveCell.Select
Dim last As Long
Range("C2").Select
Range(Selection, Selection.End(xlToRight)).AutoFill Destination:=Range("C2:C" & last)
Selection.End(xlDown).Select
Selection.ClearContents
ActiveCell.Offset(-1, 0).Range("A1").Select
Range(Selection, Selection.End(xlUp)).Select
Selection.Copy
Range("B2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Columns("C:C").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
Range("A1").Select
End Sub
You do not need such a lengthy process. You can do it in just couple of lines. For example
rng.SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "=R[-1]C"
Here is an example. Assuming that your range is from C2 onwards as shown below.
Try this code
Option Explicit
Sub Sample()
Dim ws As Worksheet
Set ws = Sheets("Table")
Dim lRow As Long
With ws
lRow = .Range("C" & .Rows.Count).End(xlUp).Row
Dim rng As Range
Set rng = .Range("C3:C" & lRow)
Dim visibleCells As Range
On Error Resume Next
Set visibleCells = rng.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not visibleCells Is Nothing Then
visibleCells.FormulaR1C1 = "=R[-1]C"
End If
End With
End Sub
In Action
Worth a Mention
Also avoid using Select/Selection/Activecell etc. You may want to read up on How to avoid using Select in Excel VBA
You do not need VBA to achieve what you want. You can achieve the same using few clicks.
NON VBA Method
Select your range. In this case C3:C13
Press CTRL + G to bring up the Go To dialog box
Click Special button
Select the Blanks radio button and click OK.
In the Formula bar type =C2 and press CTRL + ENTER key and you are done
In Action
I want to merge the first and the last row using the =cell1&cell2 function of the table but was unable to as the number of row can be dynamic.
Tried using the relative distance using ctrl+up but to no avail.
Ideally a VBA code where I can use the "&" function to merge the most top and last row of the table then paste special on top as text
Sub Macro9()
ActiveCell.FormulaR1C1 = "=R[-9]C&R[-2]C"
ActiveCell.Select
Selection.Copy
Selection.End(xlUp).Select
Selection.End(xlToRight).Select
ActiveCell.Offset(2, 0).Range("A1").Select
Range(Selection, Selection.End(xlToLeft)).Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.Copy
Selection.End(xlUp).Select
Selection.End(xlUp).Select
Selection.End(xlUp).Select
Selection.End(xlToLeft).Select
ActiveCell.Offset(0, 1).Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
If I understand correctly , what you want is a way to address the last cell in a column.
You can do this as follows:
Set sht = Sheets("main")
column = 1
lastRow = sht.Cells(sht.Rows.Count, column).End(xlUp).Row
Set lastCell = sht.Cells(lastRow, column)
lastCell is a range variable referencing the last cell in the column specified by the column variable. I explicitly referenced the sheet to avoid problems with active sheets.
Sub MergeCells()
col = 1 // column A
lastRow = Cells(Rows.Count, 1).End(xlUp).row
Mcell = Cells(1, col) & Cells(lastRow, col)
End Sub
I am trying to copy the same row of information from a sheet called "Report" (numbers will change), and paste the values into a sheet "Data" that has headers in the first row.
I tried piecing together some code from various questions.
Here is my code:
Sub Insert_Data()
'
' Insert_Data Macro
Sheets("Report").Range("B9:F9").Copy
Sheets("Data").Range("A1").PasteSpecial Paste:=xlPasteValues,
Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Sub PSData_Transfer()
Sheets("Report").Range("B9:F9").Copy
Dim lastrow As Long
lastrow = Sheets("Data").Range("A65536").End(xlUp).Row
Sheets("Data").Activate
Cells(lastrow + 1, 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End Sub
You may have to modify this a little bit to work with your code, but feel free to use mine that I'm using in my current worksheet and it works perfect!
Sub Insert_Data()
For R = LR To 2 Step -1 ' Change the 2 in "To 2" to the row just below your header,
' but typically row 2 is the second cell under header anyways
Call CopyTo(Worksheets(2).Range("B" & R & ":C" & R), Worksheets(1)Range("A:B"))
Next R
End Sub
Private Function CopyTo(rngSource As Range, rngDest As Range)
LR = rngDest.cells(Rows.Count, 1).End(xlUp).row
rngDest.cells(LR + 1, 1).value = rngSource.cells(1, 1).value
rngDest.cells(LR + 1, 2).value = rngSource.cells(1, 2).value
End Function
I don't like to use the copy method as it's slow and it likes to copy all the extra jargin, where as getting the value is much faster and it's retrieving ONLY the value
This is what I have so far. I need a sub to copy a group of cells and paste their values on the next empty cell available. The error I'm getting is in selecting that first available cell. Any thoughts?
Dim workline As Integer
Sub Test()
With ActiveSheet
workline = 11
While .Cells(workline, 2) <> Empty
workline = workline + 1
Wend
End With
Range("B3:CH9").Select
Selection.Copy
range(workline,2) .Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Message = MsgBox("Data copied succesfully", vbInformation + vbOKOnly, "Aecon Mining")
End Sub`
Not tested in Excel, but should work, or at least pointing you to the right direction:
Range("B3:CH9").Copy
Range("B2").end(xlDown).offset(1,0).paste 'first available cell
And stop using those .Select and selection everywhere, they are a total waste of time.