Opening an excel file & copying sheets using VBA - excel

I need to copy a couple of excel sheets ("Y", "X") from one file to the same sheet in another excel file (call it Z - the same file that I'm using the VBA on).
my limitation is that the name and path of the first excel file (with the X,Y) are changing, therefore I'm trying to write something more generic using the "as String" and the Application.GetOpenFilename() command but I'm receiving an error.
Tried to separate into 2 different subs
Sub BrowseForFile()
Dim sFileName As String
sFileName = Application.GetOpenFilename(, , "open the file: " )
If sFileName = "false" Then Exit Sub
MsgBox sFileName
Workbooks.Open (sFileName)
Workbooks(sFileName).Sheets("X").Activate
Stop
Runtime Error 9
file doesn't find (1004 I think)

If the user presses the Cancel button then the GetOpenFilename function returns a boolean False not a string "false" so you need to test for If sFileName = False Then and declare it as Variant.
If you open a workbook always reference it to a variable so you can use that to access the workbook easily
Dim OpenedWb As Workbook
Set OpenedWb = Workbooks.Open(sFileName)
Then you can use the variable Wb to reference the workbook you opened
OpenedWb.Worksheets("X").Activate
Note that using .Select and .Activate is a bad practice and should be avoided (How to avoid using Select in Excel VBA). Instead use another reference to reference your workbook.
Dim ws As Worksheet
Set ws = OpenedWb.Worksheets("X")
And access a range like ws.Range("A1").Value for example.
Sub BrowseForFile()
Dim sFileName As Variant 'needs to be variant because cancel returns a boolean False
sFileName = Application.GetOpenFilename(, , "open the file: " )
If sFileName = False Then Exit Sub
MsgBox sFileName
Dim OpenedWb As Workbook
Set OpenedWb = Workbooks.Open(sFileName)
Dim ws As Worksheet
Set ws = OpenedWb.Worksheets("X")
MsgBox ws.Range("A1").Value 'output the value of `A1` in worksheet `X` of workbook `sFileName`
End Sub

Related

Workbook.name property does not return the name of an excel file

I use the code below to write the names of the workbooks open in Microsoft Excel in an array, but it does not return the name of a freshly open excel file that was generated from SQL Server using template file (.xltm), knowing that the user account is a domain user. So, is it because of template or the domain user account? and how can I solve this problem and get the name of such file?
For Each AWB In Application.Workbooks
If AWB.Name <> ThisWorkbook.Name Then
WB_Array(i) = AWB.Name
i = i + 1
End If
Next AWB
Thanks
Extending the great answer in the link that Tim Williams gave in the comments, if the issue is that the other workbook is open in a different instance of Excel, you won't be able to find it by just looking in Application.Workbooks. You will need to get all the open Excel.Application Objects and then check each of their Application.Workbooks collections.
Credit to Florent B. for their code. Add their code to your project. Then use the following function to collect each workbook into a Dictionary. I have included an example of how to use that function to collect all the workbook names into an array.
Sub Example()
Dim AllWorkbooks As Object
Set AllWorkbooks = GetAllWorkbooks
'AllWorkbooks.Keys() is now an array containing the names of all open workbooks
'AllWorkbooks.Items() is now an array of all open workbook objects
End Sub
Function GetAllWorkbooks() As Object
Dim xlWorkbooks As Object
Set xlWorkbooks = CreateObject("Scripting.Dictionary")
Dim xl As Application
For Each xl In GetExcelInstances()
Dim WB As Workbook
For Each WB In xl.Workbooks
If Not xlWorkbooks.Exists(WB.Name) Then xlWorkbooks.Add WB.Name, WB
Next
Next
Set GetAllWorkbooks = xlWorkbooks
End Function
Open Workbooks to Array
Option Explicit
Sub ListWorkbookNames()
Dim wbCount As Long: wbCount = Workbooks.Count
If wbCount = 1 Then
MsgBox "Only the workbook containing this code is open.", vbExclamation
Exit Sub
End If
Dim WorkbookNames() As String: ReDim WorkbookNames(1 To wbCount - 1)
Dim wb As Workbook
Dim n As Long
For Each wb In Workbooks
If Not wb Is ThisWorkbook Then
n = n + 1
WorkbookNames(n) = wb.Name
End If
Next wb
MsgBox "Found the following open workbooks:" & vbLf _
& Join(WorkbookNames, vbLf), vbInformation
End Sub

How do I have a user select an already open excel file to import data to, and paste into the file they choose? (VBA)

Amateur Coder here.
Currently, I have this Macro linked via button. The goal is the following:
A. Once button is pressed, prompts users to select an excel workbook to Import data to, I have the following code for this part:
Sub select_file()
Dim FileSelect As FileDialog
Dim PathA As String
Set FileSelect = Application.FileDialog(msoFileDialogFilePicker)
With FileSelect
.Title = "Please Select the Doc you want to import Data to"
.AllowMultiSelect = False
.ButtonName = "Confirm"
If .Show = -1 Then
PathA = .SelectedItems(1)
Else
End
End If
End With
Workbooks.Open Filename:=PathA
End Sub
B. Once selected, begins to copy and paste data in an absolute manner/HardCoded. (I know its discouraged, but cell will not change ever) OR hard write the following formula into the destination cell. Please Assume F26 is from the destination document.
=IF(F26='[source.xlsm]Sheet1'!E10,'[Source.xlsm]Sheet1'!G10,"#REF")
How do I make Part B occur without recording it as a macro? Better yet, how do I make it plop that data into the destination?
Edit 1: The paste portion is me using the if function for verification.
If you insist on making the user identify the correct workbook/worksheet, then you can try something like this:
Sub Main_Sub()
Dim SourceWB As Workbook
Set SourceWB = ManualSelectWorkbook
' >>> Following line are only to demonstrate
' selected workbook is saved as "SourceWB"
Debug.Print SourceWB.Sheets(1).Range("A1").Value
SourceWB.Activate
End Sub
Function ManualSelectWorkbook() As Workbook
' > Variables
Dim WB As Workbook 'Possible Destination Workbook
Dim Dict As Object 'Dictionary of workbook names
Dim PromptText As String 'Inputbox Text Prompt
Dim WBselected As Integer 'Index number of selected workbook
Dim I As Integer 'Iterations
' > Variable Prep
I = 1
PromptText = ""
Set Dict = CreateObject("Scripting.Dictionary")
' > Store names of each open workbook
For Each WB In Application.Workbooks
Dict.Add I, WB.Name
PromptText = PromptText & "#" & I & " = " & WB.Name & vbCrLf
I = I + 1
Next WB
' > Ask user which workbook they wish to use
WBselected = InputBox("Please indicate which workbook you would like this data copied to:" & vbCrLf & vbCrLf & _
PromptText & vbCrLf & _
"Must be integer.", "Workbook Selection", "1")
' > Set Function = selected workbook
'Debug.Print Dict(WBselected)
Set ManualSelectWorkbook = Workbooks(Dict(WBselected))
' > Clear dictionary
Dict.RemoveAll
End Function
You can even do the exact same thing inside the selected workbook to identify the correct worksheet.
-
On the otherhand, if you know the partial name of the output workbook, you can use something like this:
Sub ExampleSub()
'Sub to initiate function
AlternateEnding.Activate
End Sub
Function AlternateEnding() As Workbook
Dim WB As Workbook
For Each WB In Application.Workbooks
If WB.Name Like "*Insert partial workbook name*" Then '<<< Must Leave asterixes.
AlternateEnding = WB
Exit Function
End If
Next WB
End Function

What is the code to skip or replace the existing data in the sheet being added?

Here is my code of adding a sheet in multiple workbooks. I want to know how to skip or replace the exiting data in those multiple workbooks.
Sub AddingChklist()
ActiveWorkbook.Save
Dim path As String
Dim file As String
Dim Chklist As Workbook
path = "C:\Users\Documents\Macro Project\"
file = Dir(path)
Application.ScreenUpdating = False
Do While Not file = ""
Workbooks.Open (path & file)
Set Chklist = ActiveWorkbook
Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Name = "Recon Checklist"
ThisWorkbook.Sheets("Recon Checklist").Range("A1:C25").Copy Destination:=Chklist.Sheets("Recon Checklist").Range("A1")
Range("A1:C25").EntireColumn.AutoFit
Range("A1:C25").EntireRow.AutoFit
Chklist.Save
Chklist.Close
file = Dir
Loop
Application.ScreenUpdating = True
MsgBox "Checklist has been added to all the files"
End Sub
Copied from discussion below:-
My question was if the recon checklist sheet was already in one of the workbooks while running this macro. How we need to skip or replace the existing sheet.
Please try this code. In order to do away with the heavy flicker connected with opening many files in succession this procedure creates an invisible instance of Excel dedicated to this task. While this works very smoothly, it unfortunately raises the problem of not being able to copy formatting from one instance of Excel to another. Therefore my code only copies values. However, you have full access to each new sheet. For now only AutoFit is applied but you could do a lot of more formatting at that point if you feel the need.
Sub AddingChklist()
' 242
Const WsName As String = "Recon Checklist" ' Ws actual name
Dim Xl As New Excel.Application ' dedicated instance of Excel
Dim ChkList As Variant ' Checklist
Dim Path As String
Dim File As String
Dim Sp() As String ' split of File
Dim Wb As Workbook ' loop object
Dim Ws As Worksheet ' loop object: CheckList
Xl.Visible = True ' hide the newly opened workbooks
Path = "C:\Users\Documents\Macro Project\"
ChkList = ThisWorkbook.Sheets(WsName).Range("A1:C25").Value
File = Dir(Path)
Do While Not File = ""
Sp = Split(File, ".") ' process only Excel workbooks
If InStr(1, Sp(UBound(Sp)), "xls", vbTextCompare) = 1 Then
Set Wb = Xl.Workbooks.Open(Path & File)
Application.StatusBar = "Processing " & Wb.Name
On Error Resume Next
Set Ws = Wb.Worksheets(WsName)
If Err.Number = 9 Then
On Error GoTo 0
Set Ws = Wb.Sheets.Add(Before:=Wb.Sheets(1))
Ws.Name = WsName
End If
With Ws
.Cells.ClearContents
.Cells(1, 1).Resize(UBound(ChkList), UBound(ChkList, 2)).Value = ChkList
.Columns.AutoFit
.Rows.AutoFit
End With
Wb.Close SaveChanges:=True
End If
File = Dir
Loop
Xl.Quit ' close the dedicated instance of Excel
' MsgBox "Checklist has been added to all the files"
Application.StatusBar = "Checklist has been added to all the files"
End Sub
Observe that the code first looks for an existing tab by the same name. If such a sheet doesn't exist it will be created. Any existing sheet will be wiped clean. Finally, the contents of your template will be pasted to the new/clean sheet.
Note that I added a test to the code to ensure that only Excel workbooks will be processed.

Copy columns in a new workbook; Run-time error

At "New folder" I have the excel workbooks which will be opened by the loop; I want to copy 2 columns in each of these workbooks and paste it in another workbook called "new"
When I run the code I get the Run-time error '91': Object variable or With block variable not set
at line With wb.Worksheets(5) and only data of the first workbook are copied.
How can I fix it?
Option Explicit
Sub ProcessFiles()
Dim Filename, Pathname As String
Dim wb As Workbook
Dim wbMain As Workbook
Dim i As Integer
Set wbMain = Workbooks.Open("C:\Users\A\Desktop\VBA\new.xlsx")
Pathname = "C:\Users\A\Desktop\VBA\New folder\"
Filename = Dir(Pathname)
i = 1
Do While Filename <> ""
Set wb = Workbooks.Open(Pathname & Filename)
Enter_Formulas wb, wbMain, i
wb.Close SaveChanges:=True
Filename = Dir()
i = i + 2
Loop
End Sub
Sub Enter_Formulas(wb As Workbook, wbMain As Workbook, i)
With wb.Worksheets(5)
.Columns(1).Copy Destination:=wbMain.Worksheets(2).Columns(i)
.Columns(3).Copy Destination:=wbMain.Worksheets(2).Columns(i + 1)
End With
End Sub
You are telling VBA to copy columns A and C from the 5th worksheet of the opened workbook. Seems like it doesn't have five or more sheets.

VBA: copy range of data across workbooks and "save as" function in loop

I want to copy a range of cells in my .csv file into a template.csv (named "pp"). Then I would like to save the template as "name of the original .csv file_2", without closing the original template as I would need it to do this procedure in loop for all the files in my folder. I have come up with this code that doesn't work:
Sub LoopThroughDirectory()
Dim MyFile As String
Dim pp As Workbook ' Workbook to receive the copied data
Dim ppSht As Worksheet ' Worksheet where copied data will be inserted
Dim Wkb As Workbook ' Temporary workbook for the Loop
Dim Sht As Worksheet ' Temporary worksheet variable for the loop
MyFile = Dir("R:\COMT study\Silvia\Cognitive data\COMT 1\Tasks\CPT*.csv*")
Set pp = Workbooks("pp.csv")
Set ppSht = pp.Sheets("Sheet1")
Do While MyFile <> ""
Set Wkb = Workbook.Open("R:\COMT study\Silvia\Cognitive data\COMT 1\Tasks\CPT" & MyFile)
Set Sht = Wkb.Worksheets("sheet1")
Sht.Range("A1:G113").Copy
With ppSht
.Range("A1:G113").PasteSpecial xlPasteFormulas
End With
pp.SaveCopyAs Filename = MyFile_2.csv
Wkb.Close True
MyFile = Dir
Loop
End Sub
I am new to the vba coding and I am not sure what I am doing wrong as I don't get any error messages, the code simply doesn't run. Do you have any suggestion?
First of all I would like to recommend you how to use a CSV file (Comma-separated values). By this a csv file does not have any sheets. Therefore you can reach the worksheet with the following, there wb is the workbook. Another good advice is to use Option Explicit that enables some error codes, example if you get to initialize a variable.
Dim pp As Workbook
pp.Worksheets (1)
Do While MyFile <> ""
Set wb = Workbooks.Open("R:\COMT study\Silvia\Cognitive data\COMT 1\Tasks\CPT" & MyFile)
With wb.Worksheets(1)
Range(A1,G113).copy
End With
With ppSht
.Range(A1,G113).PasteSpecial xlPasteFormulas
End With
pp.SaveCopyAs Filename = "MyFile_2.csv"
'Remove the wb.Close if you want the sheet to stay open (Not recommended if there are many files)
wb.Close
MyFile = Dir
loop
Try using some of this (Haven't tried it so just use it as a template). See if you can get any errors or at least if you can collect the data from the file into a array.

Resources