I run VBA code in Access and update an existing Excel file.
I have to create xls files for each sales person and update the cells by grouping customer of monthly sales point by exporting data from an Access accdb file which is connected to Oracle database by ODBC driver.
We have about 50 sales persons and will have to create 2 files on each. If I can not fix the problem I will have 100 Excel processes on my PC. It might be frozen when run even if I successfully run the accdb with VBA.
Problems:
Can not close Excel process by Application.Quit which I tried to
open a xls file by Excel.Application.Workbooks object and it seems
be it's caught the xls file still even I used .Close
SaveChanges:=True
Can not process the VBA code again against same file cause of the
previous excel file operation process is left which I confirmed it
on task manager that I have to kill the process manually every time.
I googled on the internet and MSDN site. I could not find any good solution.
Option Compare Database
Const TARGET_SHEET = "SalesObjectiveSheet"
Const FILE_CREATION_WORK_FOLDER As String = "Work"
Const DESTINATION_ROOTPATH As String = "C:\Users\Administrator\Desktop"
Const TARGET_SHEET2 As String = "SalesObjectivesSheet"
Const HEADING_LINE_POSITION As Integer = 3
Public objApp As Excel.Application
Public objBooks As Excel.Workbooks
Public objBook As Excel.Workbook
Public objSheets As Excel.Worksheets
Public objSheet As Excel.Worksheet
Public Sub test200()
Dim str As Boolean
On Error GoTo Err_Handler
strSalesName = "SalesName"
strSalesOffice = "Tokyo"
strTargetFolder = DESTINATION_ROOTPATH & "\" & FILE_CREATION_WORK_FOLDER
strTargetFileName = "SalesObjectiveSheet_201708.xlsx"
strTargetFullPath = strTargetFolder & "\" & strTargetFileName
Set objApp = CreateObject("Excel.Application")
Set objBook = objApp.Workbooks.Open(strTargetFullPath)
Set objSheet = objBook.Worksheets(TARGET_SHEET2)
If EditObjectSheetHeader(objSheet, objApp, objBook, _
objBooks, strSalesName, strSalesOffice, strTargetFileName) = False Then
GoTo Err_Handler
End If
Exit_Handler:
objApp.Quit
Set objSheet = Nothing
Set objBooks = Nothing
Set objApp = Nothing
Exit Sub
Err_Handler:
' SysCmd acSysCmdRemoveMeter
Resume Exit_Handler
End Sub
Function EditObjectSheetHeader(objSheet As Object, objApp As Object, objBook As Object, _
objBooks As Object, strSalesName, strSalesOffice, strTargetFileName) As Boolean
Dim strProcedureName As String
Dim strMonth As String
On Error GoTo Err_Handler
objSheet.Select
objSheet.Activate
strProcedureName = "EditObjectSheetHeader"
EditObjectSheetHeader = False
With objSheet.PageSetup
.CenterHeader = "&14 " & "Month Sales Objectives"
.RightHeader = "" & Chr(10) & "Sales Office:" & strSalesOffice & " Name:" & strSalesName
.CenterFooter = "&P/&N"
.PrintTitleRows = "$1:$" & HEADING_LINE_POSITION
.LeftHeader = ""
End With
Exit_Handler:
Workbooks(strTargetFileName).Close SaveChanges:=True
' Frozen after I run the VBA code once cause of previous & _
process use same file is existed it seems be.
' ActiveWorkbook.Close saveChanges:=True
' Frozen after I run the VBA code once cause of & _
previous process use same file is existed & _
(Object and With is not defined error)
' objBook.Close SaveChanges:=True
' Frozen after I run the VBA code once cause of & _
previous process use same file is existed & _
it seems be.
' ActiveWorkbook.Close SaveChanges:=True
' Error unknown.
' ThisWorkbook.Save
'Error 1004 unknown.
EditObjectSheetHeader = True
Exit Function
Err_Handler:
Select Case Err.Number
Case 9
Debug.Print strProcedureName, Err.Number, Err.Description
MsgBox Err.Description & " " & Err.Number, vbOKOnly, strProcedureName
Case 70
Debug.Print strProcedureName, Err.Number, Err.Description
MsgBox Err.Description & " " & Err.Number, vbOKOnly, strProcedureName
Resume
Case Else
Debug.Print strProcedureName, Err.Number, Err.Description
MsgBox Err.Description & " " & Err.Number, vbExclamation, strProcedureName
End Select
End Function
Below line helped, but any other opened xls also will be closed:
Shell "taskkill /F /IM EXCEL.EXE /T"
Try placing objApp.Quit after releasing references.
Set objSheet = Nothing
Set objBooks = Nothing
Set objApp = Nothing
If Not objApp is Nothing Then objApp.Quit
Related
I have code that run when file Opens that renames file data in Inputbox using ActiveWorkbook.SaveAs. It works fine under following conditions.
Spreadsheet opened in "File Explorer"
Spreadsheet opened in Excel Browser screen.
When spreadsheet is opened thru Excel Open/Menu, Sub will not save new file at initial Open, but if I run sub after, no issues.
Private Sub Workbook_Open()
'Checks Status of Workbook upon Openning
Dim PON, INP As String
Dim strPath, JC As String
Dim strNewName, NewName As String
INP = Worksheets("CHK").Range("J1").Value
Worksheets("CHK").Range("Q1").Value = "Good"
Worksheets("Form").Select
Worksheets("Form").Range("C4").Select
Call Protect_All_Sheets_Pswrd
If INP = "New" Then
Call Save_PO_File
Else
If INP = "Done" Then
MsgBox "This Check List is COMPLETE!!!!!"
Call Save_PO_File
Else
Call PGUP_PGDN
UserForm2.Show
End If
End If
End Sub
Sub Save_PO_File()
Dim strPath As String
Dim strNewName, NewName As String
1000 On Error GoTo ErrorHandler
Answer = MsgBox("Do You want to start NEW Rental Checklist?", vbQuestion + vbYesNo + vbDefaultButton2)
If Answer = vbYes Then
Worksheets("CHK").Range("S6").Value = 0
PON = InputBox("Please enter PO Number to Start Checklist:", Xpos:=2880, Ypos:=1440)
If Len(PON) > 7 Then
MsgBox "PO number can only be a Maximum of 7 digits"
GoTo 1000
End If
If PON = "" Then
MsgBox "MUST ENTER PO#"
GoTo 1000
End If
strNewName = "Rental Checklist PO " + PON & ".xlsm"
strPath = ActiveWorkbook.Path
NewName = strPath & "\" & strNewName
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:=NewName
Application.DisplayAlerts = True
If ActiveWorkbook.Name <> strNewName Then
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:=NewName, FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
Application.DisplayAlerts = True
End If
MsgBox strPath & "/" & vbNewLine & vbNewLine & strNewName, , "NEW Workbook Saved As"
Call Clean_Form 'Clear Form
Worksheets("Form").Range("C9").Value = PON 'Input PO #
Worksheets("Form").Range("C4").Select
Call PGUP_PGDN
Else
Call Confirm_ADMIN
End If
Exit Sub
ErrorHandler:
MsgBox "Had Error... Check File Name"
Exit Sub
End Sub
Tried different folders, adding error checking...etc
I want to copy the data from a closed file I have selected and see it in the file containing this macro.
I am using Office365.
How can i copy data from this "FullPath" workbook ?
Private Sub PathName()
Dim FullPath As String
On Error GoTo extApp
FullPath = Application.GetOpenFilename(FileFilter:="File Filter," & _
"*.xls;*.doc;*.xlsx;*.mdb;*.ppt;*.pdf", Title:="Please Select A File")
Exit Sub
extApp: Select Case Err.Number
Case 104
MsgBox ("104")
Exit Sub
Case Else
MsgBox "Runtime Error: " & Err.Number & vbNewLine & Err.Description
Stop
Resume
End Select
End Sub
You may try the following code modication, add in your other part of code to make it work as a complete sub:
Private Sub PathName()
Dim FullPath As String
Dim wb As Workbook
Application.DisplayAlerts = False
On Error GoTo extApp
FullPath = Application.GetOpenFilename(FileFilter:="File Filter," & _
"*.xls;*.doc;*.xlsx;*.mdb;*.ppt;*.pdf", Title:="Please Select A File")
Set wb = Workbooks.Open(FullPath, , True)
wb.Worksheets("Sheet1").Range("A1:B" & lastrow).Copy
Sheet1.Range("A1").PasteSpecial xlPasteValues
'
'
'
wb.Close
Application.DisplayAlerts = True
End Sub
I am currently trying to get data recorded into excel workbooks to be automatically copied over onto one "mass data" sheet. The files are named by date ex. "5-28-17". There is one for each day of the month. I'd like to collect all data into one sheet, as previously stated, in order by date descending.
I am currently using this code which should place all of the different workbooks onto their own worksheet, but I am having issues with that as well.
Option Explicit
Const path As String = "C:\Users\dt\Desktop\dt kte\"
Sub GetSheets()
Dim FileName As String
Dim wb As Workbook
Dim sheet As Worksheet
FileName = Dir(path & "*.xls*")
Do While FileName <> ""
Set wb = Workbooks.Open(FileName:=path & FileName, ReadOnly:=True)
For Each sheet In wb.Sheets
sheet.Copy After:=ThisWorkbook.Sheets(1)
Next sheet
wb.Close
FileName = Dir()
Loop
End Sub
I am trying to do this with VBA. There are 15 columns in the sheets I'm pulling from and the sheet I want to copy to. All line up perfectly. Is there a way to move the sheets from the WB I'm currently working on which should contain a worksheet for each WB onto one mass worksheet? Or can I pull all data directly from the folder with all of the workbooks saved by date to one worksheet?
I would use this AddIn.
https://www.rondebruin.nl/win/addins/rdbmerge.htm
It will do what you want, and a whole lot more as well.
Consider using an MS Access database. Not to worry if you do not have the Office GUI .exe app installed. Because you use a Windows machine, you do have its Jet/ACE SQL Engine (.dll files).
CREATE DATABASE
Sub CreateDatabase()
On Error GoTo ErrHandle
Dim fso As Object, olDb As Object, db As Object
Const dbLangGeneral = ";LANGID=0x0409;CP=1252;COUNTRY=0"
Const strpath As String = "C:\Path\To\ExcelDatabase.accdb"
' CREATE DATABASE
Set fso = CreateObject("Scripting.FileSystemObject")
Set olDb = CreateObject("DAO.DBEngine.120")
If Not fso.FileExists(strpath) Then
Set db = olDb.CreateDatabase(strpath, dbLangGeneral)
End If
MsgBox "Successfully created database!", vbInformation
ExitSub:
Set db = Nothing: Set olDb = Nothing: Set fso = Nothing
Exit Sub
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Resume ExitSub
End Sub
CREATE, POPULATE, EXPORT EXCEL TABLE (Excel files never opened)
Sub CreateTable()
On Error GoTo ErrHandle
Dim conn As Object, rst As Object
Dim constr As String, FileName As String, i As Integer
Const xlpath As String = "C:\Users\dt\Desktop\dt kte\"
Const accpath As String = "C:\Path\To\ExcelDatabase.accdb"
' CONNECT TO DATABASE
constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & accpath & ";"
Set conn = CreateObject("ADODB.Connection")
conn.Open constr
i = 1
FileName = Dir(xlpath & "*.xls*")
Do While FileName <> ""
If i = 1 Then
' CREATE TABLE VIA MAKE TABLE QUERY
conn.Execute "SELECT * INTO MyExcelTable" _
& " FROM [Excel 12.0 Xml;HDR=Yes;" _
& " Database=" & xlpath & FileName & "].[Sheet1$]"
Else
' POPULATE VIA APPEND QUERY
conn.Execute "INSERT INTO MyExcelTable" _
& " SELECT * FROM [Excel 12.0 Xml;HDR=Yes;" _
& " Database=" & xlpath & FileName & "].[Sheet1$]"
End If
i = i + 1
FileName = Dir()
Loop
' EXPORT TO EXCEL
Set rst = CreateObject("ADODB.Recordset")
rst.Open "SELECT * FROM MyExcelTable", conn
ThisWorkbook.Worksheets("MASS_DATA").Range("A1").CopyFromRecordset rst
' CLOSE CONNECTION
rst.Close: conn.Close
MsgBox "Successfully created and populated table!", vbInformation
ExitSub:
Set rst = Nothing: Set conn = Nothing
Exit Sub
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Resume ExitSub
End Sub
I'm using the following code to save an updated workbook.
Private Sub cmdSaveUpdatedWB_Click()
On Error GoTo Err_cmdSaveUpdatedWB_Click
gwbTarget.Activate <<<<<<<<<<<<<<<<<<<<<<<
Application.DisplayAlerts = False
gwbTarget.SaveAs txtUpdWorkbookName.Value, FileFormat:=xlOpenXMLWorkbookMacroEnabled
Application.DisplayAlerts = False
frmLoanWBMain.Show
gwbTarget.Close
Set gwbTarget = Nothing
gWBPath = ""
gWBName = ""
lblWorkbookSaved.Enabled = True
cmdUpdateAnotherWorkbook.Visible = True
Exit_cmdSaveUpdatedWB_Click:
Exit Sub
Err_cmdSaveUpdatedWB_Click:
MsgBox "The following error occurred inthe [cmdSaveUpdateWB_Click] event handler." & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & "Error descriptioin: " & Err.Description
Resume Exit_cmdSaveUpdatedWB_Click
End Sub
As noted in the title, the SaveAs operation fails. I've determined that the failure is a result of having the workbook to be saved losing the focus. I can step through the code and get the error. Once the error is generated, selecting Debug in the error message box and then pressing F5 to run the code will result in the workbook saving correctly. Placing Debug.Print statements before and after the Activate method of the worbook to be saved indicates that the active wokbook is the workbook containing the code and the form used to update the workbook. Placing a print statement in the Immediate wondow that prints the ActiveWorkbook.Name will result in printing the name of the workbook to be saved - gwbTarget.Name. Pressing F5 then runs the code correctly.
I have been unable to figure out why the workbook to be saved loses the focus. I placed delays, multiple activation statements, local variables to use for the workbookto be saved, and for the name of the workbook to be saved. Any help or ideas as to why this is happening and how to fix it will be greatly appreciated.
I did make some changes. The code is listed below...
Private Sub cmdSaveUpdatedWB_Click()
On Error GoTo Err_cmdSaveUpdatedWB_Click
Dim wbSave As Workbook
Set wbSave = gwbTarget
gwbTarget.Activate
Application.DisplayAlerts = False
''''''' gwbTarget.SaveAs txtUpdWorkbookName.Value, FileFormat:=xlOpenXMLWorkbookMacroEnabled
wbSave.SaveAs fileName:=txtUpdWorkbookName.Value, FileFormat:=xlOpenXMLWorkbookMacroEnabled
Application.DisplayAlerts = False
frmLoanWBMain.Show
gwbTarget.Close
Set gwbTarget = Nothing
gWBPath = ""
gWBName = ""
lblWorkbookSaved.Enabled = True
cmdUpdateAnotherWorkbook.Visible = True
Exit_cmdSaveUpdatedWB_Click:
Set wbSave = Nothing
Exit Sub
Err_cmdSaveUpdatedWB_Click:
MsgBox "The following error occurred inthe [cmdSaveUpdateWB_Click] event handler." & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & "Error descriptioin: " & Err.Description
Resume Exit_cmdSaveUpdatedWB_Click
End Sub
I've changed the code to more closely resemble the suggestion below. The listing is below, along with the variable definitions as they were upon entry into the program. The Excel code is running in a Citrix environment which may effect timing but shouldn't have any other effect on code execution.
I deleted the other code versions for brevity. The following code is what has worked. The key issue is that the workbook to be saved must be the active workbook when the SaveAs method is invoked.
Private Sub cmdSaveUpdatedWB_Click()
On Error GoTo Err_cmdSaveUpdatedWB_Click
Dim wbSave As Workbook
Dim wsActive As Worksheet
Dim sNWBName As String
Application.DisplayAlerts = False
sNWBName = txtUpdWorkbookName.Value
Set wbSave = gwbTarget
wbSave.Activate
Set wsActive = wbSave.ActiveSheet
wbSave.SaveAs fileName:=sNWBName, FileFormat:=xlOpenXMLWorkbookMacroEnabled
Application.DisplayAlerts = True
frmLoanWBMain.Show
gwbTarget.Close
Set gwbTarget = Nothing
gWBPath = ""
gWBName = ""
lblWorkbookSaved.Enabled = True
cmdUpdateAnotherWorkbook.Visible = True
Exit_cmdSaveUpdatedWB_Click:
Set wbSave = Nothing
Exit Sub
Err_cmdSaveUpdatedWB_Click:
Dim strErrMsg As String
strErrMsg = "Error Number: " & Err.Number & " Desc: " & Err.Description & vbCrLf & _
"Source:" & Err.Source & vbCrLf & _
"Updating Workbook: " & vbCrLf & " " & gwbTarget.Name & vbCrLf & _
"Selected Worksheet: " & gwsTrgSheet.Name & vbCrLf & _
"Active Workbook: " & vbCrLf & " " & ActiveWorkbook.Name & vbCrLf & _
"Worksheet: " & ActiveSheet.Name & vbCrLf & _
"Code Segment: cmdSaveUpdatedWB_Click event handler"
RecordErrorInfo strErrMsg
Resume Exit_cmdSaveUpdatedWB_Click
End Sub
Why don't you start with something like this
Private Sub cmdSaveUpdatedWB_Click()
Dim gwbTarget As Workbook
Set gwbTarget = Workbooks("workbook_name.xlsm") 'correct extension needed, workbook must be open
wb.SaveAs Filename:=gwbTarget.Path, FileFormat:=xlOpenXMLWorkbookMacroEnabled
MsgBox "Last saved: " & gwbTarget.BuiltinDocumentProperties("Last Save Time")
End Sub
Change one thing at a time to make it more like yours and hopefully it'll all work fine!
Update
As per the comments. If you are trying to open, update and close hundreds of workbooks. You can use this as a guide:
Sub ChangeWorkbooks()
Application.ScreenUpdating = False
Dim wbPaths As Range, wbSaveFilenames As Range
With Sheet1 'you will need to update this and the ranges below
Set wbPaths = .Range("A1:A650") 'including file extensions
Set wbSaveFilenames = .Range("B1:B650") 'including file extensions
End With
Dim i As Integer, totalBooks As Integer
Dim wbTemp As Workbook
totalBooks = wbPaths.Rows.Count
For i = 1 To totalBooks
Application.StatusBar = "Updating workbook " & i & " of " & totalBooks 'display statusbar message to user
Set wbTemp = Workbooks.Open(wbPaths.Cells(i, 1), False)
'make changes to wbTemp here
wbTemp.SaveAs wbSaveFilenames.Cells(i, 1)
wbTemp.Close
Next i
Set wbTemp = Nothing
Application.ScreenUpdating = True
Applicaton.StatusBar = False
End Sub
HELP! I cannot find this anywhere... I have found plenty of explanations of .frx files but that is not the issue. I have exported 2 modules ".bas" and a userform ".frm" that also created the ".frx" binary file. The issue is that now when I import them to a new workbook with the code below, upon initializing the userform, the application opens and tries to run in the original workbook, in which I wrote the modules and designed the custom userform. Why is this happening and is there a way to get it to load the userform in the workbook that the form and modules were imported into?
Sub Import_VBA(WBName)
Dim VBc As Variant
Dim exportFolder As String, VBcExt As String, testFile As String
Dim newWB As Workbook
testFile = WBName
exportFolder = "y:\ECI\Database\Outputs\InterfaceApp"
Set newWB = Workbooks(testFile & ".xlsm")
''''' Test VBA protection
On Error Resume Next
If newWB.VBProject.Protection <> 0 Then
If Err.Number = 1004 Then
Err.Clear
MsgBox "VBA Project Object Model is protected in " & newWB.Name & vbCrLf _
& vbCrLf & "Please remove VBA protection in Trust Center to continue.", _
vbExclamation + vbOKOnly, "Error"
Set newWB = Nothing
Exit Sub
Else
MsgBox Err.Number & ": " & Err.Description, vbExclamation, "Error"
Set newWB = Nothing
Err.Clear
Exit Sub
End If
End If
''''' Add Interface App Components
For Each VBc In CreateObject("Scripting.FileSystemObject").GetFolder(exportFolder).Files
Select Case LCase(Right(VBc.Name, 4))
Case ".bas", ".frm", ".cls", ".frx"
newWB.VBProject.VBComponents.Import exportFolder & "\" & VBc.Name
End Select
Next VBc
End Sub