I have an invoice in MS access table and the invoice needs to be split according to the subsidiary field.
Private Sub CreateInv()
Dim i As Integer
Set db = CurrentDb
Set rs = db.OpenRecordset("tbl_result")
Set rs1 = db.OpenRecordset("tbl_result")
Do While rs.EOF = False
i = rs1![Subsidiary]
If rs1![Subsidiary] = "1025" Then Workbooks.Open CurrentProject.Path & "\Temp1025.xlsx"
If rs1![Subsidiary] = "1028" Then Workbooks.Open CurrentProject.Path & "\Temp1028.xlsx"
'Fill Invoice
Range("B2") = rs1![invno]
Range("C2") = rs1![vendorid]
Range("D2") = rs1![Subsidiary]
Range("E2") = rs1![InvDate]
rs1.MoveNext
If rs1.EOF = True Then GoTo Jumper
Jumper:
ActiveWorkbook.SaveAs "c:\users\nkumar\desktop\" & "sub2.xlsx"
excel.Application.DisplayAlerts = False
ActiveWorkbook.Close False
excel.Application.Quit
'excel.Application.DisplayAlerts = True
rs.MoveNext
'x = 0
If rs1.EOF = True Then Exit Sub
Loop
End Sub
Logic / Expected Output -> I have created two templates in excel. If the subsidiary is 1025 then write invoice details (table data) to Temp1025 excel file and if the subsidiary is 1028 then write invoice details (table data) to Temp1028 excel file.
Your assistance is much appreciated. Thank you in advance,
Nirmal
Should look something like this (untested, since I don't have Access):
Private Sub CreateInv()
Dim Db, s, rs As Object, xlApp As Object, wb As Object
Set Db = CurrentDb
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
For Each s In Array("1025", "1028")
'select only the records for this id
Set rs = Db.OpenRecordset("select t.invno, t.vendorid, t.subsidiary, t.invdate " & _
" from tbl_result t where t.subsidiary='" & s & "'")
'if there are records retrieved then write to Excel template
If Not rs.EOF Then
'open template based on subsidiary name
Set wb = xlApp.Workbooks.Open(CurrentProject.Path & "\Temp" & s & ".xlsx")
wb.Sheets(1).Range("B2").CopyFromRecordset rs 'write all records
wb.SaveAs "c:\users\nkumar\desktop\Sub_" & s & ".xlsx"
wb.Close False
End If
rs.Close
Next s
xlApp.Quit 'close Excel
End Sub
Related
I have an excel file and name (Test 1) in the same folder path.
And it has a value on ("Sheet1") in the range "C3".
And I want to check this value without ever opening the workbook.
Sub Check()
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
Dim mydata As String
Dim wb As Workbook
Set wb = Workbooks.Open(ThisWorkbook.Path & "\test1.xlsx")
If wb.Worksheets("Sheet1").Range("C3").Value = "a9a" <> Empty Then
MsgBox "The value is correct", 64
Else
myError:
MsgBox "The value is incorrect", 64
End If
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
End Sub
You can quickly read data from another workbook without opening it, using ADO (see https://learn.microsoft.com/en-us/previous-versions/office/troubleshoot/office-developer/transfer-excel-data-from-ado-recordset). Working sample:
Option Explicit
Sub Check()
Dim con As Object, rst As Object, tFilePath As String
Set rst = CreateObject("ADODB.Recordset")
Set con = CreateObject("ADODB.Connection")
tFilePath = ThisWorkbook.Path & "\test1.xlsx"
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & tFilePath & ";" & _
"Extended Properties='Excel 12.0;HDR=NO';"
rst.Open "SELECT * FROM [Sheet1$C3:C3]", con, 3, 1
If rst.Fields(0).Value = "a9a" Then
MsgBox "The value is correct", 64
Else
MsgBox "The value is incorrect", 64
End If
rst.Close: Set rst = Nothing
con.Close: Set con = Nothing
End Sub
I need to create a new Excel file with data from a main (with VBA) Excel file.
I can only Save as and it is saving my main Excel file.
I need a copy of this file with certain cells and columns.
How the copy of the Excel file should look
I have this.
Private Sub CommandButton2_Click()
Dim newExcel As Excel.Application
Dim newWorkbook As Excel.Workbook
Dim newWorkSheet As Excel.Worksheet
Set newExcel = CreateObject("Excel.Application")
Set newWorkbook = newExcel.Workbooks.Add
Set newWorkSheet = newWorkbook.Worksheets(1)
newWorkSheet.Range("A1") = "Klients"
newWorkSheet.Range("B1") = "Bilance 06.17"
newWorkSheet.Range("C1") = "Bilance 07.17"
newWorkSheet.Range("D1") = "Bilance 08.17"
newWorkSheet.Range("E1") = "Bilance 09.17"
newWorkSheet.Range("F1") = "Bilance 10.17"
newWorkSheet.Range("G1") = "Kopa"
newWorkSheet.Range("A2") = TextBox1.Text
newWorkSheet.Range("B2") = TextBox2.Text
newWorkSheet.Range("C2") = TextBox3.Text
newWorkSheet.Range("D2") = TextBox4.Text
newWorkSheet.Range("E2") = TextBox5.Text
newWorkSheet.Range("F2") = TextBox6.Text
newWorkSheet.Range("G2") = TextBox7.Text
With Application.FileDialog(msoFileDialogSaveAs)
.InitialFileName = "C:\Users\" & Environ("UserName") & "\Desktop\" & newExcel
.Execute
End Sub
Try maybe this:
With newExcel
.Visible = True
With .FileDialog(msoFileDialogSaveAs)
.InitialFileName = "C:\Users\" & Environ("UserName") & "\Desktop\" & newExcel.Workbooks(1).name
.Show
'.Execute
End With
' If you nedd to close
.Quit
Thisworkbook.Activate
End With
Create a new instance, copy the values to it and then save that instance(new). You haven't shown the code where you tried to save it. newWorkbook.saveas where you put the filename parameter from filedialogbox should work.
Or just do NewWorkbook.Save since it is a new workbook, the filename picker may apper by default.
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've successfully used Access VBA to export a query to .xlsx, and I have used VBA to open the .xlsx file, but now I need to do "save as" to convert the file to a .csv or, if possible, .txt. This is part of a large automated process with thousands of files, so I really can't have any manual steps. I need the process from query to .txt to be totally automated within Access VBA. Here is my current code, which successfully opens the file I've created:
Sub Export_Reduced_Inforce()
Dim Dest_Path, Dest_File As String
Dim xlApp As Object
Dest_Path = "C:\Inforce_Reduction\Result Files\"
Dest_File = "Test1"
DoCmd.TransferSpreadsheet acExport, 10, _
"0801_Reduce Inforce", Dest_Path & Dest_File, True
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
xlApp.Workbooks.Open Dest_Path & Dest_File & ".XLSX", True, False
End Sub
you can adapt this line of code to your needs:
xl2.ActiveWorkbook.SaveAs ThisWorkbook.Path & "/" & "name your file" & ".csv"
xl2= it's the excel file you wana save it so change that with xlApp or what you have declare your excel file
Just in case you want to expand you idea and export ALL objects in your DB to Text files, run the script below.
Private Sub Command4_Click()
On Error GoTo Err_ExportDatabaseObjects
Dim db As Database
'Dim db As DAO.Database
Dim td As TableDef
Dim d As Document
Dim c As Container
Dim i As Integer
Dim sExportLocation As String
Set db = CurrentDb()
sExportLocation = "C:\Users\rs17746\Desktop\Text_Files\" 'Do not forget the closing back slash! ie: C:\Temp\
For Each td In db.TableDefs 'Tables
If Left(td.Name, 4) <> "MSys" Then
DoCmd.TransferText acExportDelim, , td.Name, sExportLocation & "Table_" & td.Name & ".txt", True
End If
Next td
Set c = db.Containers("Forms")
For Each d In c.Documents
Application.SaveAsText acForm, d.Name, sExportLocation & "Form_" & d.Name & ".txt"
Next d
Set c = db.Containers("Reports")
For Each d In c.Documents
Application.SaveAsText acReport, d.Name, sExportLocation & "Report_" & d.Name & ".txt"
Next d
Set c = db.Containers("Scripts")
For Each d In c.Documents
Application.SaveAsText acMacro, d.Name, sExportLocation & "Macro_" & d.Name & ".txt"
Next d
Set c = db.Containers("Modules")
For Each d In c.Documents
Application.SaveAsText acModule, d.Name, sExportLocation & "Module_" & d.Name & ".txt"
Next d
For i = 0 To db.QueryDefs.Count - 1
Application.SaveAsText acQuery, db.QueryDefs(i).Name, sExportLocation & "Query_" & db.QueryDefs(i).Name & ".txt"
Next i
Set db = Nothing
Set c = Nothing
MsgBox "All database objects have been exported as a text file to " & sExportLocation, vbInformation
Exit_ExportDatabaseObjects:
Exit Sub
Err_ExportDatabaseObjects:
MsgBox Err.Number & " - " & Err.Description
Resume Exit_ExportDatabaseObjects
End Sub
Here is one more version for you. This will export the results of each query, each to a separate text file.
Private Sub Command0_Click()
Dim qdf As QueryDef
Dim strFileName As String
For Each qdf In CurrentDb.QueryDefs
If Left(qdf.Name, 1) <> "~" Then
'you need to figure out TransferText command. Maybe
'you won't be lazy and expect people to read it to
'you and tutor you on how it works.
strFileName = qdf.Name
'Docmd.TransferText ....
DoCmd.TransferText transferType:=acExportDelim, TableName:=strFileName, FileName:="C:\test\" & strFileName & ".txt", hasfieldnames:=True
End If
Next qdf
MsgBox "Done"
End Sub
Ok, well, you can use this, to print the actual SQL.
Private Sub Command2_Click()
Dim db As Database
Dim qr As QueryDef
Set db = CurrentDb
For Each qr In db.QueryDefs
TextOut (qr.Name)
TextOut (qr.SQL)
TextOut (String(100, "-"))
Next
End Sub
Public Sub TextOut(OutputString As String)
Dim fh As Long
fh = FreeFile
Open "C:\Users\rs17746\Desktop\Text_Files\sample.txt" For Append As fh
Print #fh, OutputString
Close fh
End Sub
I am trying to generate certificates using the records from my Excel master data file. My coding throws me a VBA error "Runtime error - 5631; Word could not merge the main document with the data source because the data records were empty or no data records matched your query options" every alternate time.
For some data, the code works, whereas for most of the time, it throws error 5631 in the line .Execute Pause:=False
There are records inside the file, so I know there is something wrong with my Query itself.
Other info:
Temp1 = Cookies mailmerge word template,
Temp2 = Chocolates mailmerge word template,
Temp3 = Drinks mailmerge word template
Sheet1 = Cookies sales excel data,
Sheet2 = Chocolates sales excel data,
Sheet3 = Drinks sales excel data
My complete code:
Sub Generate_Cert()
Dim wd As Object
Dim wdoc As Object
Dim i As Integer
Dim isInvalid As Boolean
Dim statement, fileSuffix, datasource As String
Dim aSheet As Worksheet
Dim cDir As String
Dim wdName As String
Const wdFormLetters = 0
Const wdOpenFormatAuto = 0
Const wdSendToNewDocument = 0
Const wdDefaultFirstRecord = 1
Const wdDefaultLastRecord = -16
SalesDate = Format(Worksheets("SalesMaster").Cells(2, "B").Value, "DDMMYYYY")
On Error Resume Next
'Check Word is open or not
Set wd = GetObject(, "Word.Application")
If wd Is Nothing Then
'If Not open, open Word Application
Set wd = CreateObject("Word.Application")
End If
On Error GoTo 0
'Getting datasource
datasource = ThisWorkbook.Path & "\" & ThisWorkbook.Name
'Looping all sheet from workbook
For Each aSheet In ThisWorkbook.Sheets
'If the first cell is not empty
If aSheet.Range("A2").Value <> "" Then
isInvalid = False
'Check sheet for SQLStatement and save file name.
Select Case aSheet.Name
Case "Sheet1"
statement = "SELECT * FROM `Sheet1$`"
fileSuffix = " Cookies Sales"
i = 1
Case "Sheet2"
statement = "SELECT * FROM `Sheet2$`"
fileSuffix = " Chocolates Sales"
i = 2
Case "Sheet3"
statement = "SELECT * FROM `Sheet3$`"
fileSuffix = " Drinks Sales"
i = 3
Case Else
isInvalid = True
End Select
'If sheet should save as word
If Not isInvalid Then
'Getting new word document
Set wdoc = wd.Documents.Open("C:\Desktop\Sales Certs\Temp" & i & ".docx")
With wdoc.MailMerge
.MainDocumentType = wdFormLetters
.OpenDataSource Name:=datasource, AddToRecentFiles:=False, _
Revert:=False, Format:=wdOpenFormatAuto, _
Connection:="Data Source=" & datasource & ";Mode=Read", _
SQLStatement:=statement
.Destination = wdSendToNewDocument
.SuppressBlankLines = True
With .datasource
.FirstRecord = wdDefaultFirstRecord
.LastRecord = wdDefaultLastRecord
End With
.Execute Pause:=False
End With
'wdoc.Visible = True
wdName = SalesDate & fileSuffix & ".docx"
cDir = ActiveWorkbook.Path + "\"
wd.ActiveDocument.SaveAs cDir + wdName
MsgBox SalesDate & fileSuffix & " has been generated and saved"
'wdoc.SaveAs Filename:=wdoc.Name
wdoc.Close SaveChanges:=True
End If
End If
Next aSheet
wd.Quit SaveChanges:=wdDoNotSaveChanges
End Sub
This error was occurring because my source excel document was not saved before the Mailmerge execution. No need to save the word document, as there was no pre-processing necessary before the Mailmerge execution.
So I basically declared wBook as workbook & added this : wBook.Save
Sub Generate_Cert()
Dim wd As Object
Dim wdoc As Object
Dim i As Integer
Dim isInvalid As Boolean
Dim statement, fileSuffix, datasource As String
Dim wBook As Workbook
Dim aSheet As Worksheet
Dim cDir As String
Dim wdName As String
Const wdFormLetters = 0
Const wdOpenFormatAuto = 0
Const wdSendToNewDocument = 0
Const wdDefaultFirstRecord = 1
Const wdDefaultLastRecord = -16
wBook.save '<~~~~~~~ SAVE BEFORE MAILMERGE STARTS
SalesDate = Format(Worksheets("SalesMaster").Cells(2, "B").Value, "DDMMYYYY")
On Error Resume Next
'Check Word is open or not
Set wd = GetObject(, "Word.Application")
If wd Is Nothing Then
'If Not open, open Word Application
Set wd = CreateObject("Word.Application")
End If
On Error GoTo 0
'Getting datasource
datasource = ThisWorkbook.Path & "\" & ThisWorkbook.Name
'Looping all sheet from workbook
For Each aSheet In ThisWorkbook.Sheets
'If the first cell is not empty
If aSheet.Range("A2").Value <> "" Then
isInvalid = False
'Check sheet for SQLStatement and save file name.
Select Case aSheet.Name
Case "Sheet1"
statement = "SELECT * FROM `Sheet1$`"
fileSuffix = " Cookies Sales"
i = 1
Case "Sheet2"
statement = "SELECT * FROM `Sheet2$`"
fileSuffix = " Chocolates Sales"
i = 2
Case "Sheet3"
statement = "SELECT * FROM `Sheet3$`"
fileSuffix = " Drinks Sales"
i = 3
Case Else
isInvalid = True
End Select
'If sheet should save as word
If Not isInvalid Then
'Getting new word document
Set wdoc = wd.Documents.Open("C:\Desktop\Sales Certs\Temp" & i & ".docx")
With wdoc.MailMerge
.MainDocumentType = wdFormLetters
.OpenDataSource Name:=datasource, AddToRecentFiles:=False, _
Revert:=False, Format:=wdOpenFormatAuto, _
Connection:="Data Source=" & datasource & ";Mode=Read", _
SQLStatement:=statement
.Destination = wdSendToNewDocument
.SuppressBlankLines = True
With .datasource
.FirstRecord = wdDefaultFirstRecord
.LastRecord = wdDefaultLastRecord
End With
.Execute Pause:=False
End With
'wdoc.Visible = True
wdName = SalesDate & fileSuffix & ".docx"
cDir = ActiveWorkbook.Path + "\"
wd.ActiveDocument.SaveAs cDir + wdName
MsgBox SalesDate & fileSuffix & " has been generated and saved"
'wdoc.SaveAs Filename:=wdoc.Name
wdoc.Close SaveChanges:=True
End If
End If
Next aSheet
wd.Quit SaveChanges:=wdDoNotSaveChanges
End Sub