Flattening data from oddly shaped "tables" - vba

I have a spreadsheet with hundreds of table broken out by WBS, with odd formatting.
Beginning Format
What I want it to look like
I found a solution in which the starting tables are better organized into a summary table with headers at top:
How to "flatten" or "collapse" a 2D Excel table into 1D?
The macro I used works for two tables but uses absolute references to copy and transpose the data. It's very rough, but I've included below to show that I attempted.
The column (HRS, P, etc) and row (AL, Con, IH, etc) headings don't appear to change, so I assume I need something that will find a WBS and grab this information. Another issue is that some of the tables have extra Column headings before the Travel row (see second table in screenshot).
How do I go about writing something that will search for a WBS and record the flattened data, without referencing the specific cells?
Let me know if my question is poorly worded or if more information is needed.
Code from first macro:
Attribute VB_Name = "Module2"
Sub flatten_data()
Attribute flatten_data.VB_ProcData.VB_Invoke_Func = " \n14"
'
' flatten_data Macro
'
'
Range("B1").Select
Selection.Copy
Sheets.Add After:=ActiveSheet
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A1:A42"), Type:=xlFillDefault
Range("A1:A42").Select
ActiveSheet.Previous.Select
Range("F3:K3").Select
Selection.Copy
ActiveSheet.Next.Select
ActiveWindow.SmallScroll Down:=-45
Range("B1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Application.CutCopyMode = False
Selection.Copy
Range("B7").Select
ActiveSheet.Paste
Range("B13").Select
ActiveSheet.Paste
ActiveWindow.SmallScroll Down:=6
Range("B19").Select
ActiveSheet.Paste
ActiveWindow.SmallScroll Down:=9
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("B19:B42"), Type:=xlFillDefault
Range("B19:B42").Select
ActiveSheet.Previous.Select
Range("C6").Select
Selection.Copy
ActiveSheet.Next.Select
Range("C16").Select
ActiveWindow.SmallScroll Down:=-54
Range("C1").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("C1:C6"), Type:=xlFillDefault
Range("C1:C6").Select
Selection.Copy
ActiveSheet.Previous.Select
Range("C7").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("C7:C12").Select
ActiveSheet.Paste
ActiveSheet.Previous.Select
Range("C8").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("C13:C18").Select
ActiveSheet.Paste
ActiveSheet.Previous.Select
Range("C9").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("C19:C24").Select
ActiveSheet.Paste
ActiveSheet.Previous.Select
Range("C10").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("C25:C30").Select
ActiveSheet.Paste
ActiveSheet.Previous.Select
Range("C11").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
ActiveWindow.SmallScroll Down:=12
Range("C31:C36").Select
ActiveSheet.Paste
ActiveSheet.Previous.Select
Range("C12").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("C37:C42").Select
ActiveSheet.Paste
ActiveSheet.Previous.Select
Range("F6:K6").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
ActiveWindow.SmallScroll Down:=-33
Range("D1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Range("D7").Select
ActiveSheet.Previous.Select
Range("F7:K7").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveSheet.Previous.Select
Range("F8:K8").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D13").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveSheet.Previous.Select
Range("F9:K9").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D19").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveSheet.Previous.Select
Range("F10:K10").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D25").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveWindow.SmallScroll Down:=18
ActiveSheet.Previous.Select
Range("F11:K11").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D31").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveSheet.Previous.Select
Range("F12:K12").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D37").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveSheet.Previous.Select
Range("B16").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("A43:A84").Select
ActiveSheet.Paste
Range("B1:B42").Select
Range("B42").Activate
Application.CutCopyMode = False
Selection.Copy
ActiveWindow.SmallScroll Down:=24
Range("B43").Select
ActiveSheet.Paste
Range("C1:C42").Select
Range("C42").Activate
Application.CutCopyMode = False
Selection.Copy
ActiveWindow.SmallScroll Down:=27
Range("C43").Select
ActiveSheet.Paste
ActiveSheet.Previous.Select
Range("F21:K21").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D43").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveSheet.Previous.Select
Range("F22:K22").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D49").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveSheet.Previous.Select
Range("F23:K23").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D55").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveSheet.Previous.Select
Range("F24:K24").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
ActiveWindow.SmallScroll Down:=12
Range("D61").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveSheet.Previous.Select
Range("F25:K25").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D67").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveWindow.SmallScroll Down:=21
ActiveSheet.Previous.Select
Range("F26:K26").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D73").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
ActiveSheet.Previous.Select
Range("F29:K29").Select
Application.CutCopyMode = False
Selection.Copy
ActiveSheet.Next.Select
Range("D79").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
End Sub

I'm assuming that the tables are all of the same size and relative offset to the WBS keyword. I'm also assuming that the row "Travel" isn't needed in the final output, and the subtotals will be recalculated if needed.
Option Explicit
Sub Flatten_Data()
Dim wb As Workbook
Dim ws As Worksheet
Dim GCell As Range
Dim TableCell As Range
Dim TotalTables As Integer
Dim TableNumber As Integer
Dim TableRow As Integer
Dim TableColumn As Integer
Dim ColumnHeader(6) As String
Dim RowHeader(7) As String
ColumnHeader(1) = "HRS"
ColumnHeader(2) = "P"
ColumnHeader(3) = "OH"
ColumnHeader(4) = "G"
ColumnHeader(5) = "C"
ColumnHeader(6) = "F"
RowHeader(1) = "AL"
RowHeader(2) = "Con"
RowHeader(3) = "IH"
RowHeader(4) = "Mat"
RowHeader(5) = "OD"
RowHeader(6) = "SUB"
RowHeader(7) = "Trav"
Set wb = Workbooks("Book1") ' or whatever sheet holds the source data
Set ws = Worksheets("Sheet1") ' or whatever sheet you want to copy the flattened data to
With wb
With ws
Set GCell = .Range("A:A")
TotalTables = Application.WorksheetFunction.CountIf(GCell, "WBS")
Set GCell = .Cells.Find("WBS", .Cells(1048576, 1)) ' looks for "WBS" and ensures that it finds one in A1 if it exists
For TableNumber = 1 To TotalTables
For TableRow = 1 To 7
For TableColumn = 1 To 6
Worksheets("Sheet2").Cells(TableColumn + (TableRow - 1) * 6 + (TableNumber - 1) * 42, 4) = GCell.Offset(4 + TableRow, 4 + TableColumn).Value
Worksheets("Sheet2").Cells(TableColumn + (TableRow - 1) * 6 + (TableNumber - 1) * 42, 3) = RowHeader(TableRow)
Worksheets("Sheet2").Cells(TableColumn + (TableRow - 1) * 6 + (TableNumber - 1) * 42, 2) = ColumnHeader(TableColumn)
Worksheets("Sheet2").Cells(TableColumn + (TableRow - 1) * 6 + (TableNumber - 1) * 42, 1) = "1." & TableNumber
Next TableColumn
Next TableRow
Set GCell = .Cells.FindNext(GCell)
Next TableNumber
End With
End With
End Sub
I'll leave it to you to ensure that the table numbers are correct.
And I'd avoid 'Select' like the plague for this sort of thing, it'll only slow down the code.

Related

Skip cell - Excel VBA Macro

I am working on a VBA Macro for a budget sheet. When it copies data to cell B30 I want it to look at the cell and if there is data in the cell move to B31 and so on. However, when it gets to cell B41 I want it to throw up and error message. How would I go about writing this code?
Sheets("Budget with Revenue 2017-Test").Select
Range("B18:I18").Select
Application.CutCopyMode = False
Selection.Copy
Range("B22").Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Range("Table2940[[Sum of Revenue]:[Sum of Savings]]").Select
Application.CutCopyMode = False
Selection.Copy
Range("B30").Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Range("B21:I22").Select
Range("I21").Activate
Application.CutCopyMode = False
Selection.ClearContents
Range("B14:H14").Select
Range("H14").Activate
Selection.ClearContents
Range("J2:J3").Select
Selection.ClearContents
Range("G2").Select
Selection.ClearContents

Excel VBA copy range to a new sheet after 1,048,576 rows

So I wrote a fairly simple Macro in VBA that updates a set of variables, then copying and pasting the updated values into a new sheet. The problem is that the volume is getting a bit overwhelming now, thus reaching the 1,048,576 row limit in Excel, causing the code to crash.
I would like to update it so that whenever the rows limitation is reached, the script begins copying the cells to a new sheet (say, "FinalFile2","FinalFile3", etc) until it's fully executed.
Sub KW()
'
' Exact KWs
'
Dim i, j, LastRow As Long
Dim relativePath As String
i = 2
j = 2
'LastRowValue'
Sheets("Output").Select
LastRow = Rows(Rows.Count).End(xlUp).Row - 1
'Clean final output'
Sheets("FinalFile").Select
Range("A2").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents
Range("A1").Select
'Set Variables in Variables sheet'
Do
'Var 1'
Sheets("Names").Select
Range("A" & i).Select
Selection.Copy
Sheets("Variables").Select
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Var 2'
Sheets("Names").Select
Range("B" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Variables").Select
Range("B2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Var 3'
Sheets("Names").Select
Range("C" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Variables").Select
Range("C2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Var 4'
Sheets("Names").Select
Range("D" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Variables").Select
Range("D2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Var 5'
Sheets("Names").Select
Range("E" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Variables").Select
Range("E2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Var 6'
Sheets("Names").Select
Range("F" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Variables").Select
Range("F2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Var 7'
Sheets("Names").Select
Range("G" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Variables").Select
Range("G2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Var 8'
Sheets("Names").Select
Range("H" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Variables").Select
Range("H2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Var 9'
Sheets("Names").Select
Range("I" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Variables").Select
Range("I2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Var 10'
Sheets("Names").Select
Range("J" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Variables").Select
Range("J2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Var 11'
Sheets("Names").Select
Range("K" & i).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Variables").Select
Range("K2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Copy and Paste'
Sheets("Output").Select
Range("A2:AP2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("FinalFile").Select
Range("A" & j).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'update counters'
i = i + 1
j = j + LastRow
'end of loop condition'
Sheets("Names").Select
Loop Until IsEmpty(Cells(i, 1))
End Sub
Here are some tips how to improve your code. I am not going into the issues I mentioned in my comment on the original question but just concentrate on specific parts of the code:
Remove Selections. The general pattern is instead of
something.Select
Selection.Dosomenthing
you use
something.Dosomething
In your case:
Sheets("Names").Select
Range("A" & i).Select
Selection.Copy
Sheets("Variables").Select
Range("A2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
becomes
Sheets("Names").Range("A" & i).Copy
Sheets("Variables").Range("A2").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Use variables to reference your sheets like this:
Dim nameSheet as Worksheet
Dim varSheet as Worksheet
Dim finalSheet as Worksheet
Set nameSheet = Sheets("Names")
Set varSheet = Sheets("Variables")
Set finalSheet = Sheets("FinalFile")
Now you can use
finalSheet.Range(...).Pastespecial ...
and use Set finalSheet = Sheets("FinalFile2") once you run out of space
Don't copy cells next to each other one by one. You are copying cell Ai to A2 then Bi to B2. Just copy the range Ai:Ki to A2:K2 (although I don't see the point of this)
Don't use Copy if you don't need to. Instead of
someRange.Copy
someOtherRange.PasteSpecial Paste:=xlPasteValues
you can use
someOtherRange.Value = someRange.Value
(make sure the sizes are the same)
Disable Screenupdating using Application.Screenupdating = False (set it to True after you're done) when you're doing a lot of insertions. It can speed up a macro a lot.
As to your actual question, do as Tom suggests, add
If j > 1048576 Then
j = 2
Set finalSheet = Sheets("FinalFile2") 'maybe create the new sheet at this point
End If
You can add
j = j + lastRow
If j = 1048576 Then j = 2
BUT you should definitely clean up this code. .selections are a really slow way to do stuff like this. Look into this and try to avoid .Copy & .Paste. Just set your target cells to the values of your source with an =. This also saves a lot of time.
Edit: And definitely take a look at the link posted by #arcadeprecinct

How do I access a specific workbook that I have open, without using its name?

I'm recording this macro that transfers data between a few different documents. One of the workbooks, "Transfer Template", stays constant. But the other will change. Here is the code that I am using. (I know it's slow and a lot of it is irrelevant, but I just need to make it work).
What I'm assuming is that I have to replace 'Windows("RFQ_14446.xlsm") with ActiveWorkbook or something similar.
Sub Initial_Transfer_Macro()
'
' Initial_Transfer_Macro Macro
'
'
Windows("RFQ_14446.xlsm").Activate
Range("J51").Select
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B1").Select
ActiveSheet.Paste
Windows("RFQ_14446.xlsm").Activate
Range("D27").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B2").Select
ActiveSheet.Paste
Windows("RFQ_14446.xlsm").Activate
Range("D5").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B3").Select
ActiveSheet.Paste
Windows("RFQ_14446.xlsm").Activate
Range("F2").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B4").Select
ActiveSheet.Paste
Windows("RFQ_14446.xlsm").Activate
Range("D7").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B5").Select
ActiveSheet.Paste
Windows("RFQ_14446.xlsm").Activate
Range("D18").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B6").Select
ActiveSheet.Paste
Windows("RFQ_14446.xlsm").Activate
Range("K6").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B7").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("RFQ_14446.xlsm").Activate
Range("D12").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B8").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("RFQ_14446.xlsm").Activate
Range("D22").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B9").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("RFQ_14446.xlsm").Activate
Range("D11").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B10").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("RFQ_14446.xlsm").Activate
Range("K18").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B11").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("RFQ_14446.xlsm").Activate
Range("K3").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B12").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("RFQ_14446.xlsm").Activate
Range("I13").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B14").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("RFQ_14446.xlsm").Activate
Range("I26").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("C14").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("RFQ_14446.xlsm").Activate
Range("I27").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B17").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("RFQ_14446.xlsm").Activate
Range("I5").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "36"
Range("I5").Select
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("B20").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("RFQ_14446.xlsm").Activate
Range("I26").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Transfer Template.xlsm").Activate
Range("C20").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A1").Select
Cells.Replace What:=" Rev. ", Replacement:="-", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Replace What:="RFQ ", Replacement:="", LookAt:=xlPart, SearchOrder _
:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
End Sub
Easiest way is to set references to each workbook at the start of your code:
Sub SO()
Dim thisWorkbook As Excel.Workbook
Dim otherWorkbook As Excel.Workbook
Set thisWorkbook = ActiveWorkbook
Set otherWorkbook = Workbooks("Transfer Template.xlsm")
'// ... Rest of code here
End Sub
Once this is done you can refer to that variable instead, for example:
Debug.Print thisWorkbook.Sheets.Count
or
otherWorkbook.Sheets(1).Range("A1").Value = thisWorkbook.Sheets(2).Range("B1").Value
Just crude examples but should give you the base of the logic...
Another thing worth noting is that if the code is being run from the workbook that you want to refer to, then simply using ThisWorkbook will suffice:
Sub Example()
Workbooks("Transfer Template.xlsm").Activate
MsgBox ActiveWorkbook.Name
MsgBox ThisWorkbook.Name
End Sub
If you don't know the workbook name but it is the only other one open at the same time (in the same instance of Excel), you can loop through them like this:
Sub TransferTemplate()
Dim wbTemplate As Workbook: Set wbTemplate = ActiveWorkbook
Dim wbDestination As Workbook
Dim wb As Workbook
For Each wb In Workbooks
If wb.Name <> wbTemplate.Name Then
Set wbDestination = wb
End If
Next wb
'Example copy
wbTemplate.Worksheets(1).Range("B1").Value = wbDestination.Worksheets(1).Range("J51").Value
End Sub

Mass edit multiple workbooks of the same format

I'm very new to VBA (as of this morning), so excuse my ignorance. I have a few hundred Excel workbooks, all formatted exactly the same way (just with different text). I'm trying to both format and delete a few sheets within the workbooks (the same for alL).
I recorded a macro that works fine when applied individually, but I'm getting a runtime error when I try to run this as a means of mass format:
Sub LoopFiles()
Dim MyFileName, MyPath As String
Dim MyBook As Workbook
MyPath = "I:\Academic Networks\All scorecard copies, 6.18.2015"
MyFileName = Dir(MyPath & "*.xlsm")
Do Until MyFileName = ""
Workbooks.Open MyPath & MyFileName
Set MyBook = ActiveWorkbook
Application.Run "Workbook1.xlsm!ScorecardMacro"
MyBook.Save
MyBook.Close
MyFileName = Dir
Loop
End Sub
I keep getting a runtime error (9) - Subscript out of range. Any thoughts?
Here's the formatting/deleting I'm trying to apply to all my workbooks (which works fine when applied to one workbook at a time:
Sub ScorecardMacro()
'
' Scorecard Macro
'
'
Sheets.Add
Sheets("Scorecard").Select
Range("D3:D36").Select
Selection.Copy
Sheets("Sheet1").Select
Range("B1").Select
Selection.PasteSpecial Paste:=xlAll, Operation:=xlNone, SkipBlanks:=False _
, Transpose:=True
Sheets("Scorecard").Select
Range("A3:A36").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("B2").Select
Selection.PasteSpecial Paste:=xlAll, Operation:=xlNone, SkipBlanks:=False _
, Transpose:=True
Sheets("Scorecard").Select
Range("F3:I36").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("B3").Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("Checklist").Select
Range("D4:D27").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
ActiveWindow.ScrollColumn = 28
Range("AJ1").Select
Selection.PasteSpecial Paste:=xlAll, Operation:=xlNone, SkipBlanks:=False _
, Transpose:=True
Sheets("Checklist").Select
Range("A4:A27").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("AJ2").Select
Selection.PasteSpecial Paste:=xlAll, Operation:=xlNone, SkipBlanks:=False _
, Transpose:=True
Sheets("Additional Information").Select
Range("A4:B14").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("BH1").Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Sheets("Program Recommendations").Select
Range("A4:D21").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1").Select
Range("BS1").Select
Selection.PasteSpecial Paste:=xlAll, Operation:=xlNone, SkipBlanks:=False _
, Transpose:=True
ActiveWindow.ScrollColumn = 1
Range("A2").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = ""
ActiveCell.FormulaR1C1 = _
"=MID(CELL(""filename""),SEARCH(""["",CELL(""filename""))+1,SEARCH(""]"",CELL(""filename""))-SEARCH(""["",CELL(""filename""))-1)"
Range("A2").Select
Selection.AutoFill Destination:=Range("A2:A6"), Type:=xlFillDefault
Range("A2:A6").Select
Sheets("Program Recommendations").Select
ActiveWindow.SelectedSheets.Delete
Sheets("Additional Information").Select
ActiveWindow.SelectedSheets.Delete
Sheets("Scorecard").Select
ActiveWindow.SelectedSheets.Delete
Sheets("Checklist").Select
ActiveWindow.SelectedSheets.Delete
End Sub
The error shows you are trying to access something that doesn't exist.
Since you are deleting something, its better to do all you updates first, then do all the deletes in the end.
If you do some deletes in between and then update, there might be some values/sheets missing
You are referring to a named range called "filename":
"=MID(CELL(""filename""),SEARCH(""["",CELL(""filename""))+1,SEARCH(""]"",CELL(""filename""))-SEARCH(""["",CELL(""filename""))-1)"
I suspect that name is not defined in the other workbooks.

how to copy a single cell to another sheet and pasting to 18 cells and loop until blanks on source sheet

hiya all thanks in advance for any help
my goal is to transfer all the data from a discount grid and converting it to a list format
i have the grid as the source sheet and i am creating a new sheet ready for import to a new system which needs it laying out in a list format
name(A)-type(B)-(C)-discount(D)
(column c must be blank)
1 i need to take the company name and copy it 17 more times (for each product type)
2 i then take the product types from the top and transpose into next column
3 i then miss out 1 column then copy and transpose in the discount values in the next column
this then needs to be repeated until it finds a blank on the source page
i have constructed a basic macro but it means ill have to redo for each customer which currently stands at 939 customers (nightmare) is there a set of commands i can put into my macro to achive this ?
here is a copy of my current code
Workbooks.Add
ChDir "F:\darren t"
ActiveWorkbook.SaveAs Filename:="F:\darren t\Ready Discount Grid.xlsx", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Windows("Tools for ball.xlsm").Activate
Workbooks.Open Filename:="F:\darren t\DISCOUNTS GRID M2M.xlsx"
Cells.Select
Selection.ClearFormats
Cells.EntireColumn.AutoFit
Range("B2:S936").Select
Range("S936").Activate
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.FormulaR1C1 = "0"
Range("A2").Select
'Create grid names
Windows("Ready Discount Grid.xlsx").Activate
Application.CutCopyMode = False
Range("A1").Select
ActiveCell.FormulaR1C1 = "Customer Account Code"
Range("B1").Select
ActiveCell.FormulaR1C1 = "Blind Type Code"
Range("C1").Select
ActiveCell.FormulaR1C1 = "Option Stock Code"
Range("D1").Select
ActiveCell.FormulaR1C1 = "Discount %"
Cells.Select
Cells.EntireColumn.AutoFit
' paste names (repeat 938 times)
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("A2").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("A2").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A2:A19"), Type:=xlFillDefault
Range("A2:A19").Select
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("A3").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("A20").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A20:A37"), Type:=xlFillDefault
Range("A20:A37").Select
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("A4").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("A38").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A38:A57"), Type:=xlFillDefault
Range("A38:A57").Select
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("A5").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("A58").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A58:A73"), Type:=xlFillDefault
Range("A58:A73").Select
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("A6").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("A74").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A74:A91"), Type:=xlFillDefault
Range("A74:A91").Select
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("A7").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("A92").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A92:A109"), Type:=xlFillDefault
Range("A92:A109").Select
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("A8").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("A110").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A110:A127"), Type:=xlFillDefault
Range("A110:A127").Select
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("A9").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("A128").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFill Destination:=Range("A128:a145"), Type:=xlFillDefault
Range("A128:A145").Select
' paste types (repeat 938 times)
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("B1:W1").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("B2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Application.CutCopyMode = False
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("B1:W1").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("B20").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Application.CutCopyMode = False
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("B1:W1").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("B38").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Application.CutCopyMode = False
'paste discount values (repeat 938 times)
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("B2:S2").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("D2").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("B3:S3").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("D20").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Windows("DISCOUNTS GRID M2M.xlsx").Activate
Range("B4:S4").Select
Selection.Copy
Windows("Ready Discount Grid.xlsx").Activate
Range("D38").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
'Put rest of the data below here
End Sub
there must be a much more efficent way to do this
any help would be amazing
This could help
Do while activecell.value <> ""
'Code that must repeat
Activecell.Offset(1,0).Active 'Moves the active cell
Loop
activecell.value
Evaluates the activecell value, which one in the case that it's empty will stop