copy every cells in a column to particular cell in new sheet every time with a loop - excel

I seek your help to copy the cell values in (column D) of the first worksheet to a specified cell location in 16 existing worksheets
i want value in
D2 in in sheet1 to sheet2 (G5)
D3 in in sheet1 to sheet3 (G5)
D4 in in sheet1 to sheet4 (G5)
and so on until the D16 is copied to G5 of sheet16
i am a newbie, i looked into several answers and tried to work out on my own but.... nothing happened
Sub latitude()
Dim WS_Count As Integer
Dim I As Integer
WS_Count = ActiveWorkbook.Worksheets.Count
For I = 1 To WS_Count
Do Until IsEmpty(ActiveCell)
Sheets("Calculations").Select
Range("d2").Copy
ActiveCell.Offset(1, 0).Select
'at this point i want it to copy "D3" on next loop
ActiveSheet.Range("G5").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Loop
ActiveSheet.Next.Select
' and because the "Sheets("Calculations").Select" above takes it to the first sheet the whole script is a waste till now
Next I
End Sub

Alistairs attempt is good, i would however not use shtname = "Sheet" & i, instead try the following solution and think about bulletprooving it a bit (existance of worksheets) ;)
Sub Copy_to_G5()
Dim i As Integer
With Application
.DisplayAlerts = False
.ScreenUpdating = False
End With
i = 2
Do Until i = 17
With ThisWorkbook
.Worksheets(1).Cells(i, 4).Copy
.Worksheets(i).Range("G5").PasteSpecial
End With
i = i + 1
Loop
With Application
.DisplayAlerts = True
.ScreenUpdating = True
End With
End Sub

Give this a try.
Option Explicit
Sub Copy_to_G5()
Dim sht1 As Worksheet, ws As Worksheet
Dim i As Integer
Dim shtname As String
With Application
.DisplayAlerts = False
.ScreenUpdating = False
End With
Set sht1 = Sheets("Sheet1")
i = 2
Do Until i = 17
shtname = "Sheet" & i
sht1.Cells(i, 4).Copy
Sheets(shtname).Range("G5").PasteSpecial
i = i + 1
Loop
With Application
.DisplayAlerts = True
.ScreenUpdating = True
End With
End Sub

Related

Is there any way to fix this loop in VBA Excel?

I have few sheets in my Excel. I want this code to apply Some specific Sheet. Since I am not good at vba I am unable to do it. Please somebody help me. How do I add Sheet3 to 17 to this code so that code only run for these sheets.
Sub insertRowsSheets()
' Disable Excel properties before macro runs
With Application
.Calculation = xlCalculationManual
.EnableEvents = False
.ScreenUpdating = False
End With
' Declare object variables
Dim ws As Worksheet, iCountRows As Integer
Dim activeSheet As Worksheet, activeRow As Long
Dim startSheet As String
' State activeRow
activeRow = ActiveCell.Row
' Save initial active sheet selection
startSheet = ThisWorkbook.activeSheet.Name
' Trigger input message to appear - in terms of how many rows to insert
iCountRows = Application.InputBox(Prompt:="How many rows do you want to insert, starting with row " _
& activeRow & "?", Type:=1)
' Error handling - end the macro if a zero, negative integer or non-integer value is entered
If iCountRows = False Or iCountRows <= 0 Then End
' Loop through the worksheets in active workbook
For Each ws In ActiveWorkbook.Sheets
ws.Activate
Rows(activeRow & ":" & activeRow + iCountRows - 1).Insert
Range("A9").Select
Range("A8:C8").Select
Selection.Copy
Range("A9").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Range("D8:J8").Select
Selection.AutoFill Destination:=Range("D8:J9")
Range("D8:J9").Select
Range("K8:L8").Select
Selection.Copy
Range("K9").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Range("M8:T8").Select
Selection.AutoFill Destination:=Range("M8:T9")
Range("M8:T9").Select
Range("A8").Select
Next ws
' Move cursor back to intial worksheet
Worksheets(startSheet).Select
Range("A8").Select
' Re-enable Excel properties once macro is complete
With Application
.Calculation = xlCalculationAutomatic
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
Update Worksheets
This should work the same way as before.
At least it should help you to figure out how to loop through an array of worksheet names instead of the worksheets collection.
I could not figure out the logic of copying and filling. Shouldn't you be filling as many rows as the user selected starting from the active row?
The Code
Option Explicit
Sub insertRowsSheets()
' Define Worksheet Names Array.
Dim wsNames As Variant ' Tab names, not code names.
wsNames = Array("Sheet3", "Sheet4", "Sheet5", "Sheet6", "Sheet7", _
"Sheet8", "Sheet9", "Sheet10", "Sheet11", "Sheet12", _
"Sheet13", "Sheet14", "Sheet15", "Sheet16", "Sheet17")
' Declare object variables
Dim wb As Workbook
Dim ws As Worksheet
Dim RowsCount As Long
Dim ActiveRow As Long
Dim StartSheet As String
Dim i As Long
' Define workbook.
Set wb = ThisWorkbook ' The workbook containing this code.
' State activeRow
ActiveRow = ActiveCell.Row
' Trigger input message to appear - in terms of how many rows to insert
RowsCount = Application.InputBox(Prompt:="How many rows do you want to insert, starting with row " _
& ActiveRow & "?", Type:=1)
' Error handling - end the macro if a zero, negative integer or non-integer value is entered
If RowsCount = False Or RowsCount <= 0 Then Exit Sub
' Loop through the worksheets.
For i = LBound(wsNames) To UBound(wsNames)
With wb.Worksheets(wsNames(i))
.Rows(ActiveRow & ":" & ActiveRow + RowsCount - 1).Insert
.Range("A9:C9").Value = .Range("A8:C8").Value
.Range("D8:J8").AutoFill Destination:=.Range("D8:J9")
.Range("K9:L9").Value = .Range("K8:L8").Value
.Range("M8:T8").AutoFill Destination:=.Range("M8:T9")
End With
Next i
End Sub
' Loop through the worksheets in active workbook
For i = 3 To 17 Step 1 'This runs from the 3rd Sheet to the 17th irrespective of the name. Use array method if the sheets are mixed up
If WorksheetIDExists(i, ActiveWorkbook) Then
Set ws = ActiveWorkbook.Worksheets(i)
With ws
.Rows(activeRow & ":" & activeRow + iCountRows - 1).Insert '<- Kindly note that, if the active row is above A8, the whole script becomes a mess
.Range("A8:C8").Copy
.Range("A9").PasteSpecial Paste:=xlPasteValues
.Range("D8:J9").FillDown
.Range("K8:L8").Copy
.Range("K9").PasteSpecial Paste:=xlPasteValues
.Range("M8:T8").FillDown
.Range("A8").Select
End With
End If
Next i
Add this Function as well.
Function WorksheetIDExists(shtid As Integer, wb As Workbook) As Boolean
Dim sht As Worksheet
On Error Resume Next
Set sht = wb.Worksheets(shtid)
On Error GoTo 0
WorksheetIDExists = Not sht Is Nothing
End Function

Speeding up macro that goes through a workbook overwriting sheets by value

I made an Excel VBA macro that goes through a workbook sheet by sheet and if the sheet contains no pivots it will overwrite it by value. Unfortunately, on at least one workbook it takes so long that I can go through each sheet myself faster. I am wondering what to do to speed it up. Can anyone suggest what I need to do to accomplish this?
' Convert entire workbook's worksheets to values
'
Sub workbook_overrideSheetsToValues_noSave()
Dim answer As Long, c As Long, ws As Worksheet, report As String
answer = MsgBox("Overwrite formulas in this workbook?", vbYesNo + vbQuestion, "Warning! Formula overwrite!")
If answer = vbNo Then Exit Sub
For Each ws In Worksheets
' only copy over by value if there aren't any pivot tables in the sheet.
If ws.PivotTables.count = 0 Then
Call copySheetByValue(ws.Name)
' save all sheets being skipped
Else
c = c + 1
report = report & Chr(10) & c & ". " & ws.Name
End If
Next ws
If report <> "" Then Call MsgBox("Sheets with pivots were skipped:" & report, 0, "Warning!")
End Sub
Sub copySheetByValue(sheetName As Variant, Optional cellPos As String = "A1")
Dim vFlag As Boolean
' Handle case where sheet is hidden
If sheets(sheetName).Visible = False Then
sheets(sheetName).Visible = True
vFlag = True
End If
Worksheets(sheetName).Unprotect
On Error Resume Next
Worksheets(sheetName).ShowAllData ' Clear filters on all columns
Worksheets(sheetName).Cells.EntireColumn.Hidden = False ' Unhide all columns
On Error GoTo 0
Worksheets(sheetName).Cells.Copy
Worksheets(sheetName).Cells.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Application.Goto Worksheets(sheetName).Range(cellPos)
' Hide sheet if it was unhidden above
If vFlag = True Then
sheets(sheetName).Visible = False
vFlag = False
End If
End Sub
The workbook where it works really slowly has 27 worksheets with 12 containing pivots. The 15 remaining each have under 1000 rows with the exception of one containing 24000. Doing a Ctrl-A, Ctrl-C and then pasting by value only takes a moment when done manually.
Ben,
First thing would be to add a few controls to make sure Excel isn't allowed to calculated things:
Application.ScreenUpdating=False
Application.Calculation = xlCalculationManual 'xlCalculationAutomatic to revert back
Application.EnableEvents = False
Application.DisplayAlerts = False
Application.DisplayStatusBar = False
Application.StatusBar = False
Then, you did a great thing using Worksheets(sheetName) to make sure your code really execute on the good worksheet but you should really encapsulate it in a With block to avoid the code to evaluate what this Worksheet object is:
With Worksheets(sheetName)
' Handle case where sheet is hidden
If .Visible = False Then
.Visible = True
vFlag = True
....
' Hide sheet if it was unhidden above
If vFlag = True Then
.Visible = False
vFlag = False
End If
End with
Finally, think about writing the value to your cell instead of doing a copy-paste, because copy-paste is really slow. Think about limiting your macro to the range your worksheet really use.
'Supposing your data start at A1
Dim EndRow As Long
Dim EndColumn As Long
With Worksheets(sheetName)
EndRow = .Range("A" & .Rows.Count).End(xlUp).Row
EndColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
.Range(.Cells(1, 1), .Cells(EndColumn, EndColumn)).Value2 = .Range(.Cells(1, 1), .Cells(EndColumn, EndColumn)).Value2
End With

Excel VBA macro works randomly

i need some advice regarding this macro.
This macro cuts and copies from "LATURAP" sheet, rows if specific conditions are met. exmpl. starts with number 170889 and so on.
Problem is that, when i run this macro, it will only works once when i have imported this to excel.
Can somebody explain what i'm missing here?
Sub Laturap()
Dim i As Integer
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
a = Worksheets("LATURAP").Cells(Rows.Count, "A").End(xlUp).Row
For i = 3 To a
'selection from LATURAP to 1708
If Left(Range("A" & i), 6) = 170889
Then
Worksheets("LATURAP").Range("A:J").Rows(i).Cut
Worksheets("1708").Activate
b = Worksheets("1708").Cells(Rows.Count, "A").End(xlUp).Row
Worksheets("1708").Cells(b + 1, 1).Select
Worksheets("1708").Paste
Worksheets("LATURAP").Activate
.........
You could try this(comments added in code)...
Sub Laturap()
Dim ws1 As Worksheet, ws2 As Worksheet, i As Long
Set ws1 = ThisWorkbook.Sheets("LATURAP")
Set ws2 = ThisWorkbook.Sheets("1708")
x = 1
With ws1 'wrap your code in the worksheet variable
For i = 3 To .Cells(.Rows.Count, 1).End(xlUp).Row 'you can assign the last row as a variable and use it, this cuts down the lines of code
If Left(.Range("A" & i), 6) = 170889 Then 'check the first 6 characters in each cell in Col A for the value
With .Range("A" & i).Resize(, 10) 'if a match select the range in the row from Col A to Col J using resize.
.Copy Destination:=ws2.Cells(Rows.Count, 1).End(xlUp).Offset(x, 1) 'copy the range pan paste to the first cell in ColB in ws2
.Clear 'clear the range in ws1
x = x + 1 'increases 1 to paste to the next empty row, must be within the If statement
End With
End If
Next i
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
End Sub

VBA Runtime Error 1004 on Range.Clear

There are a lot of threads about this error, but I can't get this to work no matter what I try. Most people say it occurs when you try to invoke a method on an inactive sheet, but you shouldn't have to do that. Error is on line 28. Thanks.
Private Sub CommandButton1_Click()
Dim x As Integer
Dim boisePaste As Integer
Dim jrgPaste As Integer
Dim master As Integer
Dim lastRow As Integer
Dim bookCount As Integer
bookCount = Application.Workbooks.Count
For x = 1 To bookCount
If Left(Application.Workbooks(x).Name, 14) = "ITEM_INVENTORY" Then
boisePaste = x
ElseIf Left(Application.Workbooks(x).Name, 6) = "report" Then
jrgPaste = x
ElseIf Left(Application.Workbooks(x).Name, 8) = "Portland" Then
master = x
End If
next x
'Unhide sheets and delete Boise range'
Application.ActiveWorkbook.Sheets("BoisePaste").Visible = True
Sheets("JRGpaste").Visible = True
lastRow = Sheets("BoisePaste").Cells(Rows.Count, "B").End(xlUp).Row
Sheets("BoisePaste").Range(Cells(1,2), Cells(lastRow, 23)).Clear
'Open Boise file and copy range, paste in master'
Application.Workbooks(boisePaste).Activate
With ActiveSheet
.Range(.Cells(1,1), .Cells((.Cells(Rows.Count, "A").End(xlUp).Row),22)).Copy
End With
Application.Workbooks(master).Sheets("BoisePaste").Range(B1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
'Open JRG report and copy range, paste in master'
Application.Workbooks(jrgPaste).Activate
ActiveSheet.Cells.Copy
Application.Workbooks(master).Sheets("JRGpaste").Range(A1).Paste
Application.CutCopyMode = False
'Refresh pivot tables; hide sheets'
Application.Workbooks(master).Activate
With ActiveWorkbook
.RefreshAll
.RefreshAll
.Sheets("BoisePaste").Visible = False
.Sheets("BoisePaste").Visible = False
End With
End Sub
You need to explicitly state which sheet you want the Rows.Count and other such Range uses (Columns,Rows,Cells,etc.) will be on.
Try this:
Sheets("BoisePaste").Range(Sheets("BoisePaste").Cells(1,2), Sheets("BoisePaste").Cells(lastRow, 23)).Clear
So, go through your code and make sure you do this everywhere...i.e. in .Range(.Cells(1,1), .Cells((.Cells(Rows.Count, "A").End(xlUp).Row),22)).Copy, you didn't do it to Rows.Count, so add the sheet there too, to prevent any unexpected actions.
Think of it like this perhaps, with the line
myVariable = Sheets("mySheet").Range(Cells(1,1),Cells(1,2)).Value
VBA is reading that as
In mySheet, look for a range. What range? Hm, the user says Cells(1,1) and Cells(1,2), but what sheet does he want that? The current activesheet is called yourSheet...He specified where the Range should be (sheet called mySheet), but he didn't on Cells(), so I don't know what he wants! mySheet cells(1,1) or yourSheet cells(1,1) ??
(and yes, that's exactly how a computer thinks :P)
Edit: I went through and tried to help tighten up your code. But, as you can see perhaps, I'm not quite positive as to what you want to do, but this should give you some help/insight:
Private Sub CommandButton1_Click()
Dim x As Integer
Dim boisePaste As Integer
Dim jrgPaste As Integer
Dim master As Integer
Dim lastRow As Integer
Dim bookCount As Integer
bookCount = Application.Workbooks.Count
' Create variables to hold the workbook and sheet names.
Dim jrgWS As Worksheet, boiseWS As Worksheet
Dim masterWB As Workbook
Set masterWB = Workbooks(master)
Set jrgWS = Sheets("JRGPaste")
Set boiseWS = Sheets("BoisePaste")
For x = 1 To bookCount
If Left(Application.Workbooks(x).Name, 14) = "ITEM_INVENTORY" Then
boisePaste = x
ElseIf Left(Application.Workbooks(x).Name, 6) = "report" Then
jrgPaste = x
ElseIf Left(Application.Workbooks(x).Name, 8) = "Portland" Then
master = x
End If
Next x
'Unhide sheets and delete Boise range'
Application.ActiveWorkbook.Sheets("BoisePaste").Visible = True
jrgWS.Visible = True
With boiseWS
lastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
.Range(.Cells(1, 2), .Cells(lastRow, 23)).Clear
End With
'Open Boise file and copy range, paste in master'
'' DONT USE ACTIVE SHEET! Use your variables instead
'Application.Workbooks(boisePaste).Activate
With boiseWS
'Since you want values (xlPasteValues), just set the two ranges equal instead of copy/paste
.Range("B1").Value = .Range(.Cells(1, 1), .Cells((.Cells(.Rows.Count, "A").End(xlUp).Row), 22)).Value
End With
'Open JRG report and copy range, paste in master'
' The below just pastes into the same sheet, no??
jrgWS.Cells.Copy
jrgWS.Range("A1").Paste
Application.CutCopyMode = False
'Refresh pivot tables; hide sheets'
Application.Workbooks(master).Activate
With ActiveWorkbook
.RefreshAll
.RefreshAll
.Sheets("BoisePaste").Visible = False
End With
End Sub

How can i repeat the macro for the whole range of cells and columns?

Basically i'm linking the cells of workbook1 with workbook2, what is the code to do that for the whole spreadsheet?
my fault not clearly explained, as you can see below i'm assigning the value of the cells in workbook1 from workbook2
Sub Macro2()
Windows("workbook2.xlsx").Activate
Windows("workbook1.xlsx").Activate
ActiveCell.FormulaR1C1 = _
"='[workbook2.xlsx]workbook1'!R18C1"
Range("A19").Select
ActiveCell.FormulaR1C1 = _
"='[workbook2.xlsx]workbook1'!R19C1"
Range("A20").Select
.........
End Sub
i was wondering whats the fastest way to do that for the range A9 to A120, E9 to E120, F9 to F120.....
This code will link all cells in all worksheets:
Sub LinkSheets()
Dim ws As Worksheet
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
For Each ws In Worksheets
ws.UsedRange.FormulaR1C1 = "='[workbook2.xlsx]" & ws.Name & "'!RC"
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
If you only want to link certain cells from one workhsheet, try this code:
Sub LinkRange()
Workbooks("workbook1.xlsx").Worksheets("Sheet1"). _
Range("A9:A120,E9:E120,F9:F120").FormulaR1C1= _
"='[workbook2.xlsx]Sheet1'!RC"
End Sub
Sub CopyPasteEntries()
Dim i, g, h As Integer
Sheets("Sheet1").Select
Range("A1").EntireRow.Copy
Sheets("Sheet2").Range("A1").PasteSpecial Paste:=xlPasteAll
i = 2
Sheets("Sheet1").Select
Do Until IsEmpty(Cells(i, 1))
i = i + 1
Loop
g = i - 1
h = 2
For i = 2 To g
Sheets("Sheet1").Select
If Cells(i, 1).Value <> "Created" Then
Cells(i, 1).EntireRow.Copy
Sheets("Sheet2").Select
Cells(h, 1).Select
ActiveCell.PasteSpecial xlPasteAll
h = h + 1
End If
Next
Application.CutCopyMode = False
End Sub

Resources