I'm a very novice VBA programmer. I only get to do it in my downtime between work things. Anyways I have been working on an incident tracker for myself and colleagues and to help them out when I update it with new features I have been trying to add an "Import" feature.
The thing is there is a separate worksheet for each month (Jan to Dec and another sheet for overtime called OT). The code needs to copy from the correct sheet and paste into the sheet with the same name.
I can't quite get it to work though. This is what I have so far:
'Import Incident
Sub ImportIncidents()
Dim OpenFileName As String
Dim wb As Workbook
Dim ws As Worksheet
Dim myRng As Range
Dim MyWB As Workbook
'store the current workbook in a variable
Set MyWB = ActiveWorkbook
'Select and Open workbook
OpenFileName = Application.GetOpenFilename
If OpenFileName = False Then
MsgBox ("Import Failed!")
Exit Sub
End If
Set wb = Workbooks.Open(OpenFileName, UpdateLinks:=0)
'Get data
wb.Activate
For Each ws In wb.Worksheets
Set myRng = ws.Range("A6:AV45")
myRng.Copy
MyWB.Activate
Set myRng =
wb.Activate
Next
MsgBox ("Import Complete!")
End Sub
If anyone could help me out that would be amazing. I am sure I will be able to get the hang of it after I work through my VBA book properly (VBA for Dummies, ahah!) But I am having trouble finding a weekend to sit down and do it when I do a lot of overtime.
Your code isn't bad at all for a beginner. Assuming you are copying to the same range in the other sheet you only need one line in your for loop.
myRng.Copy Destination:=MyWB.Worksheets(myRng.Name).Range("A6:AV45")
This will copy everything including the formatting.
Please try the following:
If OpenFileName = "False" then
I tested from my machine and if you DIM OpenFileName as String than it will pass "False" into OpenFileName if you select nothing.
PS: Both OpenFileName = False and OpenFileName = "False" work on my end, so do anyone got the answer?
Apologies that I have not been on to respond to the suggestions that you have given me. Everything that was said helped.
Paul, listing as a Variant was the right way to go, and Thomas, the "" also helped get past the error. Unfortunately after I had done these I was met with a 400 error so there was an issue with something I had done.
In the end I was able to figure it out and the following code works... In a very crude way:
'Import Incident
Sub ImportIncidents()
Dim OpenFileName As Variant
Dim wb As Workbook
Dim ws As Worksheet
Dim myRng As Range
Dim MyWB As Workbook
'store the current workbook in a variable
Set MyWB = ActiveWorkbook
'Select and Open workbook
OpenFileName = Application.GetOpenFilename
If OpenFileName = False Then
MsgBox ("Import Failed!")
Exit Sub
End If
Set wb = Workbooks.Open(OpenFileName, UpdateLinks:=0)
'Import Data
wb.Activate
Application.DisplayAlerts = False
For Each ws In wb.Worksheets
Set myRng = ws.Range("A6:AV45")
myRng.Copy Destination:=MyWB.Worksheets(myRng.Parent.Name).Range("A6:AV45")
'ActiveWorkbook.Close = False
MyWB.Activate
Next
Application.DisplayAlerts = True
MsgBox ("Import Complete!")
End Sub
This is a great start and I am now working on having it only go through the sheets I want it to by using a for loop linked to the months of the year (which is how the sheets are laid out. I dont need to copy the data sheets after all as that may cause problems).
Thanks for all your help
Related
I have built this code which import data from a workbook and paste it to another one. The original workbook is composed by hundred of sheets (one sheet for each country, identified by the ISO 2 digit code: AE, AL, AM, AR etc...). The macro is opening each one of these sheets, copying the same cell, and printing all these cells in a new workbook.
The problem is that if, for example, the sheet F(AM) doesn't exists, the macro stops. I would like to make sure that if a sheet doesn't exist, the macro continues with all the other sheets (namely F(AR), F(AT), F(AU)) till the end.
Someone has any suggestion?
Many thanks in advance!
Sub ImportData()
Dim Wb1 As Workbook
Dim MainBook As Workbook
Dim Path As String
Dim SheetName As String
'Specify input data
Path = Worksheets("Input").Range("C6").Value
'Decide in which target sheet print the results
SheetName = "Data"
'From which sheets you need to take the data?
OriginSheet145 = "F(AE)"
OriginSheet146 = "F(AL)"
OriginSheet147 = "F(AM)"
OriginSheet148 = "F(AR)"
OriginSheet149 = "F(AT)"
OriginSheet150 = "F(AU)"
'Set the origin workbook
Set Wb1 = Workbooks.Open(Path & "_20171231.xlsx")
'Set the target workbook
Set MainBook = ThisWorkbook
'Vlookup to identify the correct data point
Wb1.Sheets(OriginSheet145).Range("N25").FormulaR1C1 = "=VLOOKUP(""010"",C[-10]:C[-7],2,FALSE)"
Wb1.Sheets(OriginSheet146).Range("N26").FormulaR1C1 = "=VLOOKUP(""010"",C[-10]:C[-7],2,FALSE)"
Wb1.Sheets(OriginSheet147).Range("N27").FormulaR1C1 = "=VLOOKUP(""010"",C[-10]:C[-7],2,FALSE)"
Wb1.Sheets(OriginSheet148).Range("N28").FormulaR1C1 = "=VLOOKUP(""010"",C[-10]:C[-7],2,FALSE)"
Wb1.Sheets(OriginSheet149).Range("N29").FormulaR1C1 = "=VLOOKUP(""010"",C[-10]:C[-7],2,FALSE)"
Wb1.Sheets(OriginSheet150).Range("N30").FormulaR1C1 = "=VLOOKUP(""010"",C[-10]:C[-7],2,FALSE)"
'Copy the data point and paste in the target sheet
Wb1.Sheets(OriginSheet145).Range("N25").Copy
MainBook.Sheets(SheetName).Range("AW5").PasteSpecial xlPasteValues
Wb1.Sheets(OriginSheet146).Range("N26").Copy
MainBook.Sheets(SheetName).Range("AW6").PasteSpecial xlPasteValues
Wb1.Sheets(OriginSheet147).Range("N27").Copy
MainBook.Sheets(SheetName).Range("AW7").PasteSpecial xlPasteValues
Wb1.Sheets(OriginSheet148).Range("N28").Copy
MainBook.Sheets(SheetName).Range("AW8").PasteSpecial xlPasteValues
Wb1.Sheets(OriginSheet149).Range("N29").Copy
MainBook.Sheets(SheetName).Range("AW9").PasteSpecial xlPasteValues
Wb1.Sheets(OriginSheet150).Range("N30").Copy
MainBook.Save
Wb1.Close savechanges:=False
MsgBox "Data: imported!"
End Sub
This function returns TRUE or FALSE, indicating whether a worksheet named in string wsName exists in workbook object
Function wsExists(wb As Workbook, wsName As String) As Boolean
Dim ws: For Each ws In wb.Sheets
wsExists = (wsName = ws.Name): If wsExists Then Exit For
Next ws
End Function
Us an IF statement to skip the applicable code if the worksheet does not exist.
Edit:
I can tell that you put a lot of work into your code, which is awesome, so don't take it the wrong way when I say it gave me anxiety so I had to simplify it. ...there are a lot of unneeded steps.
I do believe the "right way" is "whatever way works", so kudo's on getting this far. There's a steep learning curve in programming, so I figured I'd offer an alternate code block to replace yours. (The Option Explicit goes at the very top of the module, and will "force" you to properly declare/handle variables, objects, etc.)
Without seeing your data I can't guarantee this will work - in fact it very likely a cell reference wrong somewhere that you'll have to try to figure out - if you choose to use this at all.
Option Explicit
Sub ImportData()
Const SheetName = "Data" 'destination sheet name
Const sourceFile = "_20171231.xlsx" 'source filename for some reason
Dim wbSrc As Workbook, wbDest As Workbook, sht As Variant
Dim stPath As String, arrSourceSht() As Variant, inRow As Long
Set wbDest = ThisWorkbook 'dest wb object
stPath = Worksheets("Input").Range("C6").Value 'source wb stPath
'create array of source sheet names "146-150":
arrSourceSht = Array("F(AE)", "F(AL)", "F(AM)", "F(AR)", "F(AT)", "F(AU)")
Set wbSrc = Workbooks.Open(stPath & sourceFile) 'open source wb
With wbSrc
'VLookup to identify the correct data point
inRow = 5 'current input row
For Each sht In arrSourceSht
If wsExists(wbSrc, CStr(sht)) Then
wbDest.Sheets(sht).Range("AW" & inRow) = Application._
WorksheetFunction.VLookup("010", Range(.Sheets(sht).Range("N" & _
20 + inRow).Offset(-10), .Sheets(sht).Range("N" & 20 + inRow).Offset(-7)), 2, False)
End If
inRow = inRow + 1 'new input row
Next sht
wbDest.Save 'save dest
.Close savechanges:=False 'don't save source
End With
MsgBox "Data: imported!"
End Sub
Function wsExists(wb As Workbook, wsName As String) As Boolean
Dim ws: For Each ws In wb.Sheets
wsExists = (wsName = ws.Name): If wsExists Then Exit For
Next ws
End Function
Let me know if you have any questions, I can walk you through how it works if you like. (I'm on here at least once a day.)
Dim wbTarget As Workbook
Dim wbSource As Workbook
Set wbTarget = ThisWorkbook
Set wbSource = Workbooks.Open("C:\Users\alibe\Desktop\PoS\Alain.xlsx")
wbSource.Worksheets("Spain").Range("plage_sp").Copy
wbSource.Activate
Set wbTarget = ThisWorkbook
wbTarget.Worksheets("Feui1").Range("A1").PasteSpecial xlPasteAll
wbTarget.Save
wbTarget.Close
Hi everybody,
I am trying to cut and paste cells between two different workbooks. But I got failure 9 or 438 in my Paste line. May somebody give a help please.
There's a couple things we want change.
First, it's good practice to get into the habit of having excel check whether your file location exists or not. You might think you have it put in correctly, but it's always best to make sure excel feels the same way. (This also makes your code more flexible for later use.)
When opening workbooks and closing them, there's no reason to bog your system down trying to open new windows quickly. Since we don't need to see what it's doing, just that it's done it, we can turn ScreenUpdating and DisplayAlerts to false until the end of our code.
You should check the spelling on your worksheet "Feui1", that it's not actually "Feuil".
For the application of defining different ranges by workbook, we need to use .Sheets() object instead of .Worksheets()
Also, it's not common to see that you have this code in the same file that you're closing, when you're opening another file. At the end of this routine, ThisWorkbook is going to close, and wbSource will be left open. Is this intentional? Just something I thought I'd point out.
Sub CopyPasta()
Dim wbTarget As Workbook: Set wbTarget = ThisWorkbook
Dim wbSource As Workbook, sourceFile As String
sourceFile = "C:\Users\alibe\Desktop\PoS\Alain.xlsx"
Application.ScreenUpdating = False
Application.DisplayAlerts = False
If Dir(sourceFile) = "" Then 'Checks that file location exists
MsgBox "File not found.", vbCritical, "Bad File Address"
Exit Sub
End If
Set wbSource = Workbooks.Open(sourceFile)
wbSource.Sheets("Spain").Range("plage_sp").Copy
wbTarget.Sheets("Feuil").Range("A1").PasteSpecial xlPasteAll 'Spelling on 'Feuil'
Application.ScreenUpdating = True
Application.DisplayAlerts = True
wbTarget.Save
wbTarget.Close 'You want to close the workbook that this code is in?
End Sub
Few changes
Dim wbTarget As Workbook
Dim wbSource As Workbook
Set wbTarget = ThisWorkbook
Set wbSource = Workbooks.Open("C:\Users\alibe\Desktop\PoS\Alain.xlsx")
wbSource.Sheets("Spain").Range("plage_sp").Copy
wbTarget.Sheets("Feui1").Range("A1").PasteSpecial Paste:=xlPasteAll
wbTarget.Save
wbTarget.Close
It seems a normal question and I have searched and tried many suggestions here but the error persists. I want to copy a "case1" sheet from current workbook to an existing workbook(file name is "workbook2.xlsx", it has a worksheet named "case2"), then save the workbook and close it. Sometimes it works well, but most of the time I kept getting the same error. In fact I did not change any code so I don't know where went wrong.
The error shows "The object invoked has disconnected from its clients". It always breaks in the same place:
ThisWorkbook.Sheets("case1").Copy Before:=ActiveWorkbook.Sheets("Case2")
Sub CopySheet()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'open existing "workbook2.xlsx"
Workbooks.Open filename:="c:\workbook2.xlsx"
'copy a sheet named "case1" from current workbook to "workbook2.xlsx" which already has a sheet named "case2"
ThisWorkbook.Sheets("case1").Copy Before:=ActiveWorkbook.Sheets("Case2")
'close "workbook2.xlsx"
Workbooks("workbook2.xlsx").Activate
ActiveWorkbook.Close SaveChanges:=True
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Always set references to sheets and workbooks, then there is no chance of confusing which is which. This code does the same thing and should not give you any errors.
Sub CopySheet()
Dim wb1 As Workbook, ws1 As Worksheet 'Source
Dim wb2 As Workbook, ws2 As Worksheet 'Target
Set wb1 = ThisWorkbook
Set ws1 = wb1.Sheets("case1")
Set wb2 = Workbooks.Open("c:\workbook2.xlsx")
Set ws2 = wb2.Sheets("case2")
ws1.Copy Before:=ws2
wb2.Close True
End Sub
this is my first post on StackExchange! I've been using StackExchange for answers, but now i really have a question.
I am trying to add a column in excel using vba. This is procedure is part of a bigger sub function of which I created a new workbook and copy a series of sheets from a different workbook over.
Workbooks.Add
Set TTB = ActiveWorkbook
'add a bunch of sheets here
'sheetName = specific_sheet
Set ttb_sheet = TTB.Sheets(sheetName)
ttb_sheet.Columns("I:I").Insert Shift:=xlToRight
With this i get a runtime error of 1004: 'Insert method of Range class failed'
I tried following a series of questions on StackOverflow...
Select method of Range class failed via VBA
VBA error 1004 - select method of range class failed
It seems like the solution is to select the sheet first, then select the range. I have tried this and there was no luck. Anyone have any insight?
Here's my main sub code..
Sub create_TTB_workbook(TTB_name_)
'create TTB workbook
Dim wsHelper As New WorksheetHelper
Dim final_TTB As Workbook
Dim ttb_sheet As Worksheet
ttb_wb = ActiveWorkbook.name
Workbooks(ttb_wb).Activate
PCB_tab = 0
ST_COMP_tab = 0
For Each WS In Worksheets
If WS.name = "PCB_PIN_REPORT" Then
PCB_tab = 1
End If
If WS.name = "ST_PIN_REPORT" Then
ST_COMP_tab = 1
End If
Next WS
Workbooks.Add
Set TTB = ActiveWorkbook
new_ttb_wb = TTB.name
Debug.Print (new_ttb_wb)
If PCB_tab = 1 Then
wsHelper.copySheet ttb_wb, "PCB_PIN_REPORT", new_ttb_wb, "PCB_PIN_REPORT"
End If
If ST_COMP_tab = 1 Then
wsHelper.copySheet ttb_wb, "ST_PIN_REPORT", new_ttb_wb, "ST_PIN_REPORT"
End If
wsHelper.copySheet ttb_wb, TTB_name_, new_ttb_wb, TTB_name_
' TRIED A BUNCH OF METHODS here...
'Workbooks(ttb_wb).Sheets(TTB_name_).Cells.copy
'Sheets.Add.name = TTB_name_
'ActiveSheet.paste
'Sheets(TTB_name_).Activate
'Columns("I:I").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
'Worksheets(TTB_name_).Range("I1").EntireColumn.Insert
'Columns("I:I").Select
'Columns("I:I").Insert Shift:=xlToRight
Set ttb_sheet = Sheets(TTB_name_)
ttb_sheet.Columns("I:I").Insert Shift:=xlToRight
Columns("K").copy Destination:=Range("I1")
Range("I6") = "header name"
End Sub
Whenever I run into an issue like this, I always isolate the code to its simplest form. Once I get it working at that level, I add it back in to the full application and can usually figure out what I did wrong.
I've written a simple version of what you are trying to do. Note that I've included a few Debug.Print statements to help me verify what is going on. The debug messages will appear in your Immediate window. Obviously you can also step through the code and examine variables as you go.
To get this to work, create a workbook and save it as DestinationWorkbook.xlsx. Then open another workbook and insert the code below.
Sub InsertColumnInDestinationWorksheet()
Dim sourceWb As Workbook
Dim targetWb As Workbook
Dim sourceWs As Worksheet
Dim targetWs As Worksheet
Set sourceWb = ThisWorkbook
Debug.Print sourceWb.Name
Set targetWb = Workbooks("DestinationWorkbook.xlsx")
Debug.Print targetWb.Name
Set sourceWs = sourceWb.Sheets("Sheet1")
Debug.Print sourceWs.Name
Set targetWs = targetWb.Sheets("Sheet1")
Debug.Print targetWs.Name
targetWs.Range("I1").Value2 = "Moving right along..."
targetWs.Columns("I:I").Insert shift:=xlToRight
End Sub
After running the code, you can examine the target sheet. You should see the text we wrote into column I is now in column J.
This works for me when I change the variable naming to:
Sub testingg()
Dim ttb_sheet As Worksheet
Set ttb_sheet = Sheets(1)
ttb_sheet.Columns("I:I").Insert Shift:=xlToRight
End Sub
So I presume there's an issue with the way you reference the workbook when setting ttb_sheet on line 3. Note that you add a workbook but you aren't actually 'activating' it necessarily. And are you sure the 'Sheetname' actually exists in the TTB workbook?
I would like my code to open a workbook (always the same one), detect the first free row, write to just two cells in that row, and then save/close the workbook. This seems like a simple problem, but the macro seems to be opening a copy of the file, and then locking it for editing.
Can you see any errors in my open code? I know that the file opens and that the row search works, but then it 1. never writes to the cells, and 2. locks the file.
Function WriteToMaster(Num, Path) As Boolean
'Declare variables
Dim xlApp As Excel.Application
Dim wb As Workbook
Dim ws As Worksheet
Dim infoLoc As Long
Set xlApp = New Excel.Application
'Specifies where the Master Move Key is stored
Set wb = xlApp.Workbooks.Open("DOC LOCATION")
Set ws = wb.Worksheets("Sheet1")
'Loop through cells, looking for an empty one, and set that to the loan number
infoLoc = firstBlankRow(ws)
MsgBox "First blank row is " & infoLoc & ". Num is " & Num
ws.Cells(infoLoc, 1).Value = Num
ws.Cells(infoLoc, 2).Value = Path
'Save, close, and quit
wb.Save
wb.Close
xlApp.Quit
'Resets the variables
Set ws = Nothing
Set wb = Nothing
Set xlApp = Nothing
'pieces of function from http://p2p.wrox.com/vb-how/30-read-write-excel-file-using-vb6.html
End Function
Thank you again, stackoverflow <3
Do you need to open a new excel app just to open a workbook?
Can't you just do something like this:
Sub Macro1()
Dim wkb As Workbook
Workbooks.Open Filename:="\User Documents$\bob\My Documents\workbook_open_example.xlsx"
Set wkb = Workbooks("workbook_open_example.xlsx")
End Sub