VBScript on checking if the records exist - sql

I have a table and a text file. Once the records in the table copied into textfile, the records will be deleted. But the table are still in used and will be inserted with a new records from time to time(by another program). I what to do checking on How to make sure that if there are no records in the table, the program will never copy into textfile.
Any solution, or references are very thankful. Thank you very much. Im testing in WSH and using MSSQL Server 2005.
'call functions
call CopyFile()
call tblDelete()
Sub tblDelete()
Dim sql1
sql1 = "DELETE from tblOutbox"
rs = conn.Execute(sql1)
End Sub
Sub CopyFile
'set the sql command
cmd.CommandText = "SELECT * FROM tblOutbox"
cmd.CommandType = 1 ''# adCmdText Command text is a SQL query
Dim rs : Set rs = cmd.Execute
'create obj for the FileSystem
Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objFile, objFolder
Dim strDir, strFile
strDir = "c:\"
strFile = "\newFile.txt"
'check that the strDirectory folder is exist
If objFSO.FolderExists(strDir) Then
Set objFolder = objFSO.GetFolder(strDir)
Else
Set objFolder = objFSO.CreateFolder(strDirectory)
WScript.Echo "Just created " & strDir
End If
If objFSO.FileExists(strDir & strFile) Then
Set objFolder = objFSO.GetFolder(strDir)
Else
Set objFile = objFSO.CreateTextFile(strDir & strFile)
Wscript.Echo "Just created " & strDir & strFile
End If
Set objFile = Nothing
Set objFolder = Nothing
'open files and copy into
Dim objtextStream : Set objtextStream = objFSO.OpenTextFile(strDir & strFile, 8, True)
Do Until rs.EOF
objtextStream.Write rs("id") & ", "
objtextStream.Write rs("ip") & ", "
objtextStream.Write rs("msg") & ", "
objtextStream.WriteLine rs("date")
rs.MoveNext
Loop
objTextStream.WriteLine
objTextStream.WriteLine "Report Generate at " & Now
objTextStream.WriteLine "--------------------------------------------"
objtextStream.Close
rs.Close
End Sub

You could put
If rs.RecordCount > 0 Then
exit sub
End If
before
Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim objFile, objFolder
i.e. Don't execute any of the statements, if there are no records.

Can you set your code up in a format such as the following, in which you delay opening the output file until after you have fired your query and retrieved at least one response:
Set up SQL statement
Execute SQL query
init bFirstRecord as true
Loop over results
if bFirstRecord
check folder and file existence, create as necessary
open output file
bFirstRecord = false
end if
write record to output
End Loop
Close up files, etc

Related

TXT Import Add Field Using Partial Filename

I am trying to import multiple .txt files from a directory into an Access table using VBA.
I have code that currently works that imports the data and moves the files to an archive directory.
What I need to do is add the first part of the filename as field in the table, namely the date.
The file format is MMDDYYYY_LbxReport.txt (ex 02082022_LbxReport.txt)
Here is the code that I have working, and I commented out what I tried to add to fix my problem:
Private Sub Command9_Click()
On Error GoTo bImportFiles_Click_Err
Dim objFS As Object, objFolder As Object
Dim objFiles As Object, objF1 As Object
'Dim dteEntry As Variant 'added this variant for use in UPDATE cmd
Dim strFolderPath As String
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFS.GetFolder("\\*****************\upload\SSDTestLBXa\")
Set objFiles = objFolder.files
For Each objF1 In objFiles
If Right(objF1.Name, 11) = "xReport.txt" Then 'LBX level report capture
'dteEntry = Left(objF1.Name, 8)
'dteEntry = Left(dteEntry, 2) & "/" & Mid(dteEntry, 3, 2) & "/" & Right(dteEntry, 4) 'added to reformat into standard date format
DoCmd.TransferText acImportDelim, "lbxlevelspecs", "lbxlevel", strFolderPath & objF1.Name, False
'CurrentDb.Execute "Update lbxlevel" & "Set EntryDate=" & dteEntry & "", [] 'getting syntax errors here
Name strFolderPath & objF1.Name As "\\**************\upload\SSDTestLBXa\Archive\" & objF1.Name 'Move the files to the archive folder
End If
Next
Set objF1 = Nothing
Set objFiles = Nothing
Set objFolder = Nothing
Set objFS = Nothing
'Call Site_level
MsgBox ctr & "All volumes imported", , "Volume Import"
bImportFiles_Click_Exit:
Exit Sub
bImportFiles_Click_Err:
MsgBox Err.Number & " " & Err.Description
Resume bImportFiles_Click_Exit
End Sub
I saw a similar thread for this question, but I can't get the syntax right, and the OP's code was very different from what I have that's working so far.
Any help would be greatly appreciated!
This is how you would construct the update statement:
Public Sub doit()
Dim dteEntry As Variant
dteEntry = Left("02142024_SomeName.txt", 8)
dteEntry = Left(dteEntry, 2) & "/" & Mid(dteEntry, 3, 2) & "/" & Right(dteEntry, 4) 'added to reformat into standard date format
CurrentDb.Execute "ALTER TABLE lbxlevel ADD EntryDate DATETIME"
CurrentDb.Execute "Update lbxlevel " & "Set EntryDate='" & dteEntry & "'"
End Sub
Because it needs apace before 'SET', and quotation marks around the date.
EDIT: I added the ALTER TABLE, this tests successfully on my side.

How do I save attachment files to a directory and keep the file extension?

I would like to save the attachments to a directory using a new file name.
The following code renames the files but loose their extension. The files are image files.
How do I go by?
Dim strFileName As String
Dim rsParent As DAO.Recordset2
Dim rsChild As DAO.Recordset2
Dim subField As DAO.Field2
Dim strPath As String
strPath = "C:\Images"
If Len(Dir("C:\Images", vbDirectory)) = 0 Then
MkDir "C:\Images"
End If
Set rsParent = CurrentDb.OpenRecordset("tblDonations", dbOpenSnapshot)
With rsParent
If .RecordCount > 0 Then .MoveFirst
While Not .EOF
Set rsChild = rsParent("Image").Value
If rsChild.RecordCount > 0 Then rsChild.MoveFirst
While Not rsChild.EOF
Set subField = rsChild("FileData")
strFileName = strPath & "\" & .Fields("ItemNo")
If Len(Dir(strFileName)) <> 0 Then Kill strFileName
subField.SaveToFile strFileName
rsChild.MoveNext
Wend
.MoveNext
Wend
End With
subflied.Close
Set subfield = Nothing
rsChild.Close
Set rsChild = Nothing
rsParent.Close
Set rsParent = Nothing
Append file extension onto strFileName. Extract it from rsChild("FileType").
strFileName = strPath & "\" & .Fields("ItemNo") & "." & rsChild("FileType")

Read CSV/Excel file into array

I am trying to make a macro which copies emails when I receive them, and saves them in specific windows folders on a network drive based on the domain name.
The list of domains I have will be large and subject to change by users without coding experience, so I am looking to develop a text, CSV, or excel file that someone can update which lists my company's relationship to them (client, vendor, sub-contractor, etc...) and their name (both of which controls the file path), the domain name (#example.com).
I think I can figure out how to do most of that (a clever combination of nested if and for statements), but I can't figure out how to read the file into an array, and my google-fu has failed me.
I don't think it really helps, but here is the code that I shamelessly copied from the web and am planning to work off of.
Option Explicit
Private WithEvents InboxItems As Outlook.Items
Sub Application_Startup()
Dim xNameSpace As Outlook.NameSpace
Set xNameSpace = Outlook.Application.Session
Set InboxItems = xNameSpace.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub InboxItems_ItemAdd(ByVal objItem As Object)
Dim FSO
Dim xMailItem As Outlook.MailItem
Dim xFilePath As String
Dim xRegEx
Dim xFileName As String
Dim SenderAddress As String
On Error Resume Next
' Define SenderAddress as sender's email address or domain
xFilePath = PathCreator(SenderAddress)
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FolderExists(xFilePath) = False Then
FSO.CreateFolder (xFilePath)
End If
Set xRegEx = CreateObject("vbscript.regexp")
xRegEx.Global = True
xRegEx.IgnoreCase = False
xRegEx.Pattern = "\||\/|\<|\>|""|:|\*|\\|\?"
If objItem.Class = olMail Then
Set xMailItem = objItem
xFileName = xRegEx.Replace(xMailItem.Subject, "")
xMailItem.SaveAs xFilePath & "\" & xFileName & ".html", olHTML
End If
Exit Sub
End Sub
Function PathCreator(SenderAddress)
' [needs to read the file and create the path based on the values]
End Function
You can use ADODB to connect to the source file, and read it into a 2-dimensional array. Add a reference to Microsoft ActiveX Data Objects from Tools -> References.... For example, if you want to use an Excel file:
Dim excelPath As String
excelPath = "C:\path\to\excel\file.xlsx" ' Replace with the path to the Excel file
Dim connectionString As String
connectionString = _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=""" & excelPath & """;" & _
"Extended Properties=""Excel 12.0;HDR=Yes"""
'This assumes the Excel file contains column headers -- HDR=Yes
Dim sql As String
sql = "SELECT Relationship, LastName, FirstName, DomainName FROM [Sheet1$]"
'Assumes the relevant worksheet is named Sheet1
'Also assumes the first row of the sheet has the following labels: Relationship, LastName, FirstName, Domain (in no particular order)
Dim rs As New ADODB.Recordset
rs.Open sql, connectionString
Dim arr As Variant
arr = rs.GetRows 'Puts the data from the recordset into an array
rs.Close
Set rs = Nothing
Dim row As Variant, column As Variant
For row = 0 To UBound(arr, 2)
For column = 0 To UBound(arr, 1)
Debug.Print arr(column, row)
Next
Next
Using a text file or CSV is just a matter of slightly changing the connection string and the SQL. But I think using an Excel file will force the users to keep the data in columns, where in a CSV users would have to insert field- and row-separators manually; the same for any other text format -- users would have to remember the format's rules and apply them correctly.
But I question if an array is the best data structure for you to use; in this case you could use the recordset directly. In order to make sure the file is not held open, you could use a disconnected recordset. (If your intention is to find the appropriate domain name and use that to get other details, then I would suggest you load the data from a recordset into a Scripting.Dictionary.)
Also note that you probably only need to load the data from the file once, unless you expect it to change while the code is running.
I would write something like this
Dim rs As ADODB.Recordset
Function PathCreator(SenderAddress) As String
If rs Is Nothing Then
Dim excelPath As String
excelPath = "C:\path\to\excel\file.xlsx" ' Replace with the path to the Excel file
Dim connectionString As String
connectionString = _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=""" & excelPath & """;" & _
"Extended Properties=""Excel 12.0;HDR=Yes"""
Dim sql As String
sql = "SELECT Relationship, LastName, FirstName, DomainName FROM [Sheet1$]"
Set rs As New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.CursorType = adOpenStatic
rs.Open sql, connectionString, adOpenStatic, adLockBatchOptimistic
'Disconnect the recordset
rs.ActiveConnection = Nothing
'Now the data will still be available as long as the code is running
'But the connection to the Excel file will be closed
End If
'build the path here, using the recordset fields
PathCreator = rs!Relationship & "_" & rs!LastName & "_" & rs!FirstName & "_" & rs!Domain
End Function
NB. By the same token, you can add a reference to Microsoft Scripting Runtime; then you can write the code that uses the FileSystemObject as follows:
Dim FSO As New Scripting.FileSystemObject
If Not FSO.FolderExists(xFilePath) Then
FSO.CreateFolder xFilePath
End If
and with a reference to the Microsoft VBScript Regular Expressions 5.5 libary:
Set xRegEx As New VBScript_RegExp_55.RegExp
xRegEx.Global = True
xRegEx.IgnoreCase = False
xRegEx.Pattern = "\||\/|\<|\>|""|:|\*|\\|\?"
If objItem.Class = olMail Then
Set xMailItem = objItem
xFileName = xRegEx.Replace(xMailItem.Subject, "")
xMailItem.SaveAs xFilePath & "\" & xFileName & ".html", olHTML
End If

Inherited MS Access Database, Tracking Sources of Queries

I have just inherited a database at my new company. Old DB owner left no good documentation and queries very hard to keep track of. Looking for programmatic answer to track sources of fields in every query (what table it come from). Prefer something can be exported to Excel to study, Access visualization is no good. Am familiar with VBA.
This is pretty messy but could save you time collecting each query's SQL code. The following code exports all SQL stored in the QueryDefs collection into a text file. I have it splitting the code with a space delimiter, but a comma might be preferable. The data will not be normalized, I don't have the time to go to that level of complexity. Just make sure to update strPath before you execute. Hopefully this helps.
Sub PullQuerySQL()
Dim dbs As Database
Dim i As Integer
Dim fso As Object
Dim oFile As Object
Dim varParse() As String
Dim element As Variant
Dim strPath As String
strPath = ".txt"
Set dbs = CurrentDb()
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFile = fso.CreateTextFile(strPath)
For i = 0 To dbs.QueryDefs.Count - 1
oFile.WriteLine dbs.QueryDefs(i).Name
varParse = Split(dbs.QueryDefs(i).SQL, " ")
For Each element In varParse
oFile.WriteLine element
Next element
Next i
oFile.Close
Set oFile = Nothing
Set fso = Nothing
Set dbs = Nothing
End Sub
I have been through this with many inherited databases. I find it extremely helpful to create an Access table with the fields and the tables/queries that they come from. Try this code below. It will prompt you for the name of the query that you are looking to "map" as I call it. It will then create a new table named "queryName Definitions".
Option Compare Database
Public Sub MapQuery()
Dim strQueryName As String
Dim rst As DAO.Recordset
Dim fld As Field
Dim strSource As String
Dim strField As String
Dim strValue As String
Dim strSQL1 As String
Dim strSQL2 As String
Dim booExists As Boolean
strQueryName = InputBox("Please enter the name of the query that you are looking to map")
Set rst = CurrentDb.OpenRecordset(strQueryName)
On Error GoTo error1
booExists = IsObject(CurrentDb.TableDefs(strQueryName & " Definitions"))
DoCmd.DeleteObject acTable, strQueryName & " Definitions"
continue:
strSQL1 = "CREATE TABLE [" & strQueryName & " Definitions]" & " (FieldName CHAR, SourceName CHAR);"
DoCmd.RunSQL (strSQL1)
DoCmd.SetWarnings False
For Each fld In rst.Fields
strField = fld.Name
strSource = fld.SourceTable
Debug.Print strValue
strSQL2 = "INSERT INTO [" & strQueryName & " Definitions]" & "(FieldName, SourceName) VALUES(""" & strField & """, """ & strSource & """);"
DoCmd.RunSQL (strSQL2)
Next fld
error1:
If Err.Number = 3265 Then
Resume continue
Else
MsgBox Err.Description
End If
DoCmd.SetWarnings True
Exit Sub
DoCmd.SetWarnings True
End Sub

Macro enabled word documents give save changes dialogue

I've a VBA script as below.
Sub AutoOpen()
ActiveDocument.Variables("LastOpen").Value = Now()
End Sub
Sub AutoClose()
Dim objFSO, objFolder, objTextFile, objFile
Dim strDirectory, strFile, strText
strDirectory = "d:\work"
strFile = "\work.csv"
' Create the File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Check that the strDirectory folder exists
If objFSO.FolderExists(strDirectory) Then
Set objFolder = objFSO.GetFolder(strDirectory)
Else
Set objFolder = objFSO.CreateFolder(strDirectory)
Debug.Print "Just created " & strDirectory
End If
If objFSO.FileExists(strDirectory & strFile) Then
Set objFolder = objFSO.GetFolder(strDirectory)
Else
Set objFile = objFSO.CreateTextFile(strDirectory & strFile)
Debug.Print "Just created " & strDirectory & strFile
End If
Set objFile = Nothing
Set objFolder = Nothing
' OpenTextFile Method needs a Const value
' ForAppending = 8 ForReading = 1, ForWriting = 2
Const ForAppending = 8
Set objTextFile = objFSO.OpenTextFile(strDirectory & strFile, ForAppending, True)
'Build the string to write
strText = """" & ActiveDocument.FullName & """" & "," & ActiveDocument.Variables("LastOpen").Value & "," & Now()
' Writes strText every time you run this VBScript
objTextFile.WriteLine (strText)
objTextFile.Close
End Sub
here the macro is running fine, but the problem is when i open and close my word document, though there are no changes done, it asks me if i would like to save the changes like below.
please let me know how can i avoid this save dialogue box, if there are no changes made in document.
here if i open a blank document and close it, even then this is getting triggered.
As mentioned in comments, the creation of the variable in AutoOpen is causing this behavior.
Include a Save statement in AutoOpen:
Sub AutoOpen()
ActiveDocument.Variables("LastOpen").Value = Now()
ThisDocument.Save
End Sub
to avoid the Save prompt.