Copying rows and columns, including blanks, in excel vba without xlDown - vba

I'd like to copy Rows and Columns of a worksheet to a new workbook. I can open and activate the new book and new sheets, but the data I am copying is currently A1:F520 on one sheet and A1:G1031 on another. There are multiple blanks in between
and within several "groups" of data sets.
For the sake of the visual organization of our data, I want to keep those blanks in. The ranges will be changing over time, so I don't want to define something specific. I'd rather keep it general like Range("A1", Range("A1".End(xlDown)). I suppose I could just include some ridiculously large range to ensure everything is there, but I'd rather accomplish this in a more dynamic (if that is the right word) sort of way.
This is what I have so far:
Option Explicit
Public LGSheet As Worksheet
Public SGSheet As Worksheet
Public NewWorkbook As Workbook
Public UserYear As Integer
Sub DefineYear()
UserYear = Application.InputBox(Prompt:="Set Date for New Workbook", Type:=1)
Set NewWorkbook = Workbooks.Add
Set SGSheet = Worksheets.Add
Set LGSheet = Worksheets.Add
Call PasteLGTandSGT
End Sub
Sub PasteLGTandSGT()
Workbooks("Finished Products YTD Generator").Activate
Worksheets("LGT").Activate
Range("A1", Range("A1").End(xlDown)).Copy
LGSheet.Activate
Obviously I've put the xlDown bit here, and my google-fu isn't strong enough to find out anything more.

For example:
With Workbooks("Finished Products YTD Generator").Worksheets("LGT")
.Range(.Range("A1"), .Cells(Rows.Count, 1).End(xlUp).Offset(0, 7)).Copy _
LGSheet.Range("A1") 'or whatever
End With
Note that you don't need to activate sheets to copy or paste, and it's a good habit to get out of.

Related

Copy and paste data from different worksheet to another worksheet in a same excel spreadsheet

Sub Save7()
Dim NextRow As Range
Set NextRow = Range("AC" & Sheets("Sheet1").UsedRange.Rows.Count)
Sheet3.Range("AC14:AG14").Copy
Sheet1.Activate
NextRow.PasteSpecial Paste:=xlValues, Transpose:=False
Application.CutCopyMode = False
Set NextRow = Nothing
End Sub
My purpose of this code is to copy data ( Five columns of 'NO' in AC14 to AG14) from sheet 3 and paste to sheet 1 where the last active cell is at.
The code above is working well, however I made some modification to the sheet tab name for sheet 1. Sheet 1 is now called "Equipment stuffs", while sheet 3 name is remaining unchanged.
After those changes, the macro stopped working. The cause is probably because I don't know how to declare "Equipment stuffs" in the code .
There's no need to do copy/paste to move data from one place on the spreadsheet to another. You should simply assign the Value of the respective Range objects, for example:
Sheet1.Range("NamedRange2").Value = Sheet1.Range("NamedRange2").Value
Also, use code names for the sheets, instead of Sheets("SheetName"), and defined named for the ranges, instead of Range("AC14:AG14", otherwise your code will stop working if the user renames the sheet or inserts or deletes any rows above your reference.
If you want to automate this a little you could collect the active workbook and loop through each sheet using wb.Worksheets. Then collect the name with targetSheet.Name.
Option Explicit
Public Sub getSheet()
Dim wb As Workbook
Dim targetSheet As Worksheet
Set wb = ActiveWorkbook
For Each targetSheet In wb.Worksheets
Debug.Print targetSheet.Name
Next targetSheet
End Sub
I’m brazilian hehe, I understood your question , I’ve a code for alter the data in same worksheet (I’ll attach it here), for you to change the data in another worksheet, you need put on:
Worksheets("NameWorkSheet) Activate
for the VBA that’s refers to this tab.

Copying Data from External workbook based on headers not in order to another workbook

I hope this is the right place to ask this question as I am on the verge of going crazy. I am so rusty and I have zero experience with VBA (only with C++, java)
The problem:
I am trying to copy data from one workbook to another.
Lets say I have a workbook (called DATA) with several worksheets filled with data. Each column of data has a unique heading (all headings on the same row).
On the other hand I have another workbook (called REPORT) with one worksheet that contains only the heading of the data (in one row). They are not in the same order as in DATA workbook. For example I have 3 headings in REPORT worksheet that can be found in different worksheets in DATA workbook.
I need to loop through all the worksheets in the DATA workbook and copy paste the whole column to the REPORT worksheet when the same heading is found.
This image may help to understand. Explanation
Thanks ALOT for your help in advance. I have searched alot for this code but found similar stuff but didnt manage to understand any .
First attempt at doing it, but getting an error of Run-time error '1004'.
Any help?
Dim MyFile As String
Dim ws As Worksheet
''Workbook that contains one worksheet with all the headings ONLY NO DATA
Dim TargetWS As Worksheet
Set TargetWS = ActiveSheet
Dim TargetHeader As Range
''Location of Headers I want to search for in source file
Set TargetHeader = TargetWS.Range("A1:G")
''Source workbook that contains multiple sheets with data and headings _
not in same order as target file
Dim SourceWB As Workbook
Set SourceWB = Workbooks("Source.xlsx")
Dim SourceHeaderRow As Integer: SourceHeaderRow = 1
Dim SourceCell As Range
''Stores the col of the found value and the last row of data in that col
Dim RealLastRow As Long
Dim SourceCol As Integer
''Looping through all worksheets in source file, looking for the heading I want _
then copying that whole column to the target file I have
For Each ws In SourceWB.Sheets
ws.Activate
For Each Cell In TargetHeader
If Cell.Value <> "" Then
Set SourceCell = Rows(SourceHeaderRow).Find _
(Cell.Value, LookIn:=xlValues, LookAt:=xlWhole)
If Not SourceCell Is Nothing Then
SourceCol = SourceCell.Column
RealLastRow = Columns(SourceCol).Find("*", LookIn:=xlValues, _
SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
If RealLastRow > SourceHeaderRow Then
Range(Cells(SourceHeaderRow + 1, SourceCol), Cells(RealLastRow, _
SourceCol)).Copy
TargetWS.Cells(2, Cell.Column).PasteSpecial xlPasteValues
End If
End If
End If
Next
Next
Your question didn't specify what part of the problem you're actually stuck on, so I'll assume you don't know how to start. Note that nobody on here is going to provide you with the full working solution to your problem - that's upto you to figure out.
A few tips to get you to start working:
The first question you're going to ask yourself with problems involving multiple workbooks is typically going to be which workbook am i going to attach my macro to?
In your case, the REPORT Workbook looks like a saner option, since you probably want someone to be clicking on something in the report in order to generate it. You could also argue the other way around though.
Once you have chosen where to put your VBA, you have to establish a reference to the other workbook.
You either have to load the other Excel file from disk using Workbooks.Open, or have both Workbooks be open at the same time in your Excel Instance, which I'd recommend for you because it's easier. In this case simply establish the reference using the Workbooks object.
Dim exampleRefToDATA As Workbook: Set exampleRefToDATA = Workbooks("data.xlsx") ' or index
Then, cycle through each Worksheet
using something like For Each ws As WorkSheet In exampleRefToDATA.WorkSheets as your For Loop
In that Loop, loop through the first column using something like
For Each allName As Range In ws.Range(... for you to figure out ...)
In this Loop, you'll have to look if that name is in your REPORTS sheet by doing another loop like
For Each thisName As Range in Range(... seriously, there's enough on stackoverflow on how to properly iterate over the used range of a row ...)
Note how this Range() call is Equivalent to ActiveWorkbook.ActiveWorkSheet.Range, which is your Reports sheet.
Then just check for equality and copy the row over if necessary. Again, copying a row has also been covered here before.
Hope this was helpful for you.

Copy/Paste variable dataset between workbooks without clipboard

I've been trying to optimize some of my coding and managed to cut and speed it up a lot. However there are some things that are still quite clunky (and me still a noob). Backstory is that my code is opening source and target files, copies a lot of data of variable length, closes source and then does a lot of operations and finally saves target file.
One of the things Id like is to do if possible is a direct copy of data without using clipboard, activating workbooks, selecting sheets (whatever of this is possible to pack into more efficient code that I am currently having)
Windows("SOURCE.xlsm").Activate
Sheets("Data").Select
Range("A2:AX10").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Windows("TARGET.xlsm").Activate
Range("A2").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Is it possible to do a selection (A2:AX10 and all the way down to last row) in SOURCE file-Data sheet and directly copy it to TARGET file-Data sheet cell A2 without using clipboard.
The reason why I use A2:AX10 and then selection down is because I have a lot of blank cells in the whole data set and this way I get entire data.
I would like to be able to to that selection and use it as a range in this line
Workbooks(“SOURCE”).Worksheets("Data").Range(“A2:AX10 & ALLTHEWAYDOWN”).Copy _Workbooks(“TARGET”).Worksheets("Data").Range(“A2")
I was trying to solve this but I dont end up with desired result. When I try doing selection and setting as range then both trying copy range with activitng workbooks and in the direct copy mode I get 1004 error.
Is it possible to optimize this chunk and make it work. It would improve a lot of my VBA.
Thanks,
You need something like this:
With Workbooks("SOURCE.xlsm").Sheets("Data")
.Range("A2:AX10", .Range("A2:AX10").End(xlDown)).Copy Workbooks("TARGET.xlsm").ActiveSheet.Range("A2")
End With
You could probably also use CurrentRegion rather than End(xlDown
You can set one range's values (the range where you would want to paste values) equal to a source range's values (the range which you would previously have copied).
Sub paste_values()
Dim wb_A As Workbook, ws_A As Worksheet
Dim wb_B As Workbook, ws_B As Worksheet
Dim last_row As Long
Set wb_A = ThisWorkbook
Set ws_A = wb_A.Sheets(1)
Set wb_B = Workbooks("WorkbookB")
Set ws_B = wb_B.Sheets(1)
With ws_A
last_row = .Range("A" & .Rows.Count).End(xlUp).Row
End With
ws_B.Range("A2:AX" & last_row).Value = ws_A.Range("A2:AX" & last_row).Value
End Sub
This code is setting the new range's values equal to the original range. It prevents the need to activate sheets or workbooks, whilst also copying data to a range without filling the clipboard.
I would also recommend using last_row = .Range("A" & .Rows.Count).End(xlUp).Row to find the last row of your data. Although you do need to ensure you use this on a column which you know contains continuous data.

Excel to replace formulas with values

I have an Excel workbook (1) with around 9 sheets that is pulling in and manipulating data from a second workbook (2).
After pulling in the data from workbook (2) I need to be able to replace the formulas in workbook (1) to the resulting values that the formulas have produced, from here I will then save the workbook (1) with the results.
Is there a macro that can do this for me?
On your new workbook some basic code such as:
Sub Value()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Sheets
ws.UsedRange.Value = ws.UsedRange.Value
Next
End Sub
While the OP is dated, I want to make note of a non-loop method that is useful. In certain scenarios, loops can really slow down the code execution. To replace formulas in a cell --without a loop-- try:
With Sheets("example").Range("A1:C1000")
.value = .value
End With
You can revise the reference as necessary, but the execution is seamless, fast, and as a bonus - prevents range highlighting that cannot be cleared if you pursued the .copy + .pastespecial xlPasteValues approach.
What seems to work for me is to use concatenate()
So, for example, the formula I have referencing a cell from another sheet is:
=arrayformula(iferror(index('To Be Processed'!X:X,small(if($A$1='To Be
Processed'!$Y2,row('To Be Processed'!X:X)),row((2:2))),"")))
and if I change to the formula to:
=concatenate(arrayformula(iferror(index('To Be
Processed'!X:X,small(if($A$1='To Be Processed'!$Y2,row('To Be
Processed'!X:X)),row((2:2))),""))))
and it puts in the text value from the reference cell into my second sheet.
Which may or may not be helpful depending on how you populate your sheets--I'm not very good with VBA, though, which means I do more things manually :)

Gathering data with VBA from yet to be created worksheets

I have been asked to create summary worksheets for excel files that I don't populate. These are 'monthly' excel files with the worksheets 'usually' named as to the week commencing date. I say 'usually' as a spelling mistake might creep in or such that wont allow the sheet names to be predicted in advance of their creation. The worksheet wont be created until the week in question has begun.
What I am trying to do, though struggling with, is create some VBA code to copy a number of cells and ranges from each worksheet to a summary worksheet which will be hidden. The worksheets all follow the same formatting, the main info being: A1 as the weekstart date, O4 to R4 as 4 summary column headers and N5 to N30 as username info. O5 to R30 then has counts in them depending on the data within the worksheet.
I want to create some code that copies the weekstart date (A1) alongside each username that is not blank (N5:N30) and the values after in the corresponding row. As the column headers in O4 to R4 dont change these can stay static on the summary sheet.
Afraid I dont know too much about vba. I guess I would use Worksheets.Count to find the number of worksheets? Was going to modify the code on here but I dont know how to ensure each row of data goes on a new line in the summary worksheet?
use the ozgrid example but make this alteration:
.Range("A1").
to
.Range("A" & l).
then amend your original post with further questions + the actual code you are using.
I have amended ozgrid code with the following which may be more or less relevant to your query. If you can rephrase your query into a more task1, task2 way, it will then be easy to change the below script into something you want.
The below script just work as a module instead of a worksheet event which is easier to control, just create a sub module and copy paste it there then run it or you can also create a button on the worksheet to run, using developper tab and choose form or activex button linked to the macro SplitWs.
Sub SplitWs()
Dim wSheet As Worksheet, ws As Worksheet
Dim i As Long
Set wSheet = ThisWorkbook.Worksheets(1)
i = 1
With wSheet
.Columns(1).ClearContents
.Cells(1, 1) = "INDEX"
.Cells(1, 1).Name = "Index"
End With
For Each ws In Worksheets
If ws.Name <> wSheet.Name Then
i = i + 1
With wSheet
.Range("A1").Name = "Start_" & wSheet.Index
.Hyperlinks.Add Anchor:=.Range("A1"), Address:="", _
SubAddress:="Index", TextToDisplay:="Back to Index"
End With
wSheet.Hyperlinks.Add Anchor:=wSheet.Cells(i, 1), Address:="", _
SubAddress:="Start_" & wSheet.Index, TextToDisplay:=wSheet.Name
End If
Next ws
End Sub
I also change the 'l' variable into 'i' which is easier to read.
Hope it will be of help, else comment with the things to amend.
Pascal
http://multiskillz.tekcities.com