Sending reports at scheduled times - windows

I'm trying to set up automated emailing of a few reports for my company and have a few questions after doing some research into it.
So far I have the emailing portion finished and working of MS-Access where it will send emails containing two reports to whomever. I have also set up a .bat file to run the macro automatically and can use task scheduler in order to run the macro while I'm logged in and receive the emails.
The problem is I'm trying to set it up so that it will run overnight bi-weekly. When I test out the task scheduler with the option "Run whether logged on or not"(which since my account does not have admin privileges, I had to switch into an admin account and give my account log on as batch job rights) and try to run it while being logged out, unfortunately it doesn't work.
I have tried out running both Access directly through the task scheduler as well as through a .bat file. The results from the .bat file show that the operation completed successfully, but no emails will go through and as far as I know, the .bat program does not properly execute. When I attempt to run access directly through the task scheduler, the error shows that the operator or administrator has refused the request(0x800710E0).
Would I need to be running my account as a local administrator in order for this to work? Or should I try to write a batch file with AT commands to try to schedule this?
This is my first attempt at doing anything with Windows for automated scheduling as I've only ever used the crontab functions within linux. Any advice or help would be greatly appreciated, as well as any questions that might help my clarify what I'm trying to do here.
Code for the .bat file:
start "C:\Program Files (x86)\Microsoft Office\root\Office16\MSACCESS.EXE" "C:\Users\*User*\Documents\Asset List Backup 20191126.accdb" /x SendEmail
Edit:
Code for the Email:
Public Function Sendemail1()
Dim crrntdate As String
Dim ol As Outlook.Application, msg As MailItem, atts As Attachments, strFilePath As String, strFilePath2 As String
Set ol = CreateObject("Outlook.Application")
crrntdate = Format(DateValue(Now), "mmddyyyy")
strFilePath = "C:\Users\USER\Documents\Auto Reports\Office Consumables Report " & crrntdate & ".pdf"
strFilePath2 = "C:\Users\USER\Documents\Auto Reports\Field Consumables Report " & crrntdate & ".pdf"
DoCmd.OutputTo acOutputReport, "AutoCountReport", acFormatPDF, strFilePath, False
DoCmd.OutputTo acOutputReport, "AutoCountFieldReport", acFormatPDF, strFilePath2, False
DoEvents
Set msg = ol.CreateItem(olMailItem)
Set atts = msg.Attachments
With msg
.Subject = "Automatic Report for Office Consumables " & crrntdate
.Body = "Body text" 'Edited
.To = "Email" 'Edited
.CC = ""
atts.Add strFilePath
atts.Add strFilePath2
.Send
End With
End Function

Related

Exporting the SAS Project Log file

I used to run 3 SAS EG Projects on a daily basis. Since a couple of days, we have a "SAS Scheduler" that is basically running those latter during the night (the first one at 00:00 AM, second one at 01:00 AM, third one at 03:00 AM). Each SAS Project has multiple SAS Programs.
All in all, that is great news, but this also mean I can't check the logs directly anymore.
To keep track of the night jobs, I am trying to find what could be the best way to export the log files for each project. I found out about the SAS Project Log recently, which basically summarize the logs from all the programs within a SAS Project.
I discovered CaseySmith's answer on the SAS Community forum, basically tweaking the .vbs script to save the SAS Project log file to a .txt using the following code:
Set objProjectLog = objProject.ProjectLog
objProjectLog.Clear()
objProjectLog.Enabled = True
'strProjectLog = objProjectLog.Text
objProjectLog.SaveAs "c:\temp\projectLog.txt"
But, 1) It is a .txt file not a log file and 2) I don't know where to add it in my current .vbs script:
Option Explicit
Dim app
Call dowork
'shut down the app
If not (app Is Nothing) Then
app.Quit
Set app = Nothing
End If
Sub dowork()
On Error Resume Next
'----
' Start up Enterprise Guide using the project name
'----
Dim prjName
Dim prjObject
prjName = "C:\Users\kermit\Desktop\Project.egp" 'Project Name
Set app = CreateObject("SASEGObjectModel.Application.8.1")
If Checkerror("CreateObject") = True Then
Exit Sub
End If
'-----
' open the project
'-----
Set prjObject = app.Open(prjName,"")
If Checkerror("app.Open") = True Then
Exit Sub
End If
'-----
' run the project
'-----
prjObject.run
If Checkerror("Project.run") = True Then
Exit Sub
End If
'-----
' Save the new project
'-----
prjObject.Save
If Checkerror("Project.Save") = True Then
Exit Sub
End If
'-----
' Close the project
'-----
prjObject.Close
If Checkerror("Project.Close") = True Then
Exit Sub
End If
End Sub
Function Checkerror(fnName)
Checkerror = False
Dim strmsg
Dim errNum
If Err.Number <> 0 Then
strmsg = "Error #" & Hex(Err.Number) & vbCrLf & "In Function " & fnName & vbCrLf & Err.Description
'MsgBox strmsg 'Uncomment this line if you want to be notified via MessageBox of Errors in the script.
Checkerror = True
End If
End Function
In the end, what I would like is that on the morning, I run a program that scan the 3 project log files for Notes, Warning and Errors and send to myself an email with the results. Hence, is there a way to export the SAS Project Log (not manually) in a folder?
So, first, what is this code doing?
Set objProjectLog = objProject.ProjectLog
objProjectLog.Clear()
This clears the project log. This needs to be done before your project is run - otherwise the log contains data from past runs. So put this before the prjOBject.Run().
objProjectLog.Enabled = True
'strProjectLog = objProjectLog.Text
objProjectLog.SaveAs "c:\temp\projectLog.txt"
This then exports the project log to a text file. You of course can call that text file whatever you want. You need this code to appear after your program runs, and somewhere before it closes. Right after PrjObject.Run() is probably fine.
You will need to update the names to match your vbs file's names - they use objproject and your vbs uses prjObject, but those are the same thing, just match the names.
Second - what else could you do? If VBS isn't your thing, you have a lot of other ways you could do this.
Export your EG project to a .sas file, then schedule this in base SAS with the normal output options. This may also be possible via the scheduling interface.
Use PROC PRINTTO to redirect your log inside your SAS code.
Copy your EG project to a location you can see. The EG project does contain the log of everything that was run - so there's no reason you couldn't just open the .egp and look at it, just make sure you're not doing that with the production file since you might forget to close out.
My preference is not to schedule EG projects, but to schedule .sas programs; use EG as the development environment and then export to .sas. This gives you more flexibility. But there are a lot of different ways to skin this cat.

Set/adjust file version of a rtf-file with VBscript

I created a logon script to automatically create a email signature for Outlook. This script creates the following file "C:\Users\%username%\AppData\Roaming\Microsoft\Signatures\Default_signature.rtf"
I would like to add to a versionnumber to this file so I can check if an update of this file is necessary or not. If not, exit logon script. Else update signature with a higher versionnumber.
To get a versionnumber was pretty easy to find, but I couldn't find how to set/change a versionnumber with VBscript.
Using the DSOFile.OleDocumentProperties didn't work for me. I kept getting a ActiveX-error "Can't create object". It could be that I have to register
the dsofile.dll in the system but this code has to work for every user in our company and I don't want to install this on every device before I can use this logon script.
'Code for requesting versionnumber
Set objFSO = CreateObject("Scripting.FileSystemObject")
file = "C:\Users\%username%\AppData\Roaming\Microsoft\Signatures\Default_signature.rtf"
Wscript.Echo "Version = " & objFSO.GetFileVersion(file)
I hope someone could tell me how to do this :)
As far as i know DSO is the only supported way by Microsoft to change properties of the files without rewriting them. There are some VBA scripts out there for Excel, but that does not apply in your case with RTFs.
However, might i suggest a different alternative? I have in my infrastructure a script that is placed to run at each logon and checks on a share a certain file's last modified date. If the file present on the machine is older, then it's replaced by that on the share.
Dim objFSO, strFileName
strFileName = "C:\Users\user\Desktop\Tests\fdsfsd.rtf"
Set objFSO = CreateObject( "Scripting.FileSystemObject" )
WScript.Echo objFSO.GetFile( strFileName ).DateLastModified
Set objFSO = Nothing

VBA code inside Excel doesn't run when triggered via Scheduler

So the setup on this WinServer 2012 R2 64bit is:
Windows Task Scheduler -> cscript .vbs file -> opening excel and run a sub in the main module
This runs fine in the background when I double click the .vbs file, but when I trigger the .vbs via the task scheduler, excel opens, but doesn't load the file or run the sub (not sure which). The task runs under an domain user that has administration rights on the machine. I use the same user when i try clicking on the .vbs
Code that is being run, in order:
Task scheduler launches:
C:\WINDOWS\system32\cscript.exe "D:\xyz\trigger.vbs"
.vbs does:
Option Explicit
Dim xlApp, xlBook, xlsheets, xlcopy
Set xlApp = CreateObject("Excel.Application")
xlapp.Interactive = False
xlapp.DisplayAlerts = False
xlapp.AskToUpdateLinks = False
xlapp.AlertBeforeOverwriting = False
Set xlBook = xlApp.Workbooks.Open("D:\xyz\excelfile.xlsm")
On Error Resume Next
Call xlBook.Application.Run("Main.Extrnal_Trigger")
xlbook.Saved = True
xlBook.Close
xlApp.Quit
Set xlBook = Nothing
Set xlcopy = Nothing
Set xlApp = Nothing
WScript.Quit(1)
Excel code:
Sub Extrnal_Trigger()
Application.EnableEvents = False
Application.AskToUpdateLinks = False
Application.DisplayAlerts = False
Application.AlertBeforeOverwriting = False
Call update_button
Call MainProgram
Call ReportSave
End Sub
How can I find out where the .vbs or the excel hangs and why? A very similar setup on another machine does run without troubles. It is virtually identical to the code quoted here.
I realize there are several bad practices (like not cleaning up xlapp settings), but I'd like to get the process running before cleaning up.
/edit:
Removing
On Error Resume Next
from the .vbs does not display an error.
/edit2:
I tried reverting as far back as possible.
Option Explicit
Dim fso, f, s, log
Set fso = CreateObject("Scripting.FileSystemObject")
Set log = fso.CreateTextFile("D:\xyz\TESTlog.txt")
log.WriteLine "before fso"
Set f = fso.GetFile("D:\xyz\excel.xlsm")
s = f.Path & " "
s = s & "Created: " & f.DateCreated & " "
s = s & "Last Accessed: " & f.DateLastAccessed & " "
s = s & "Last Modified: " & f.DateLastModified
log.WriteLine "after fso"
log.writeline "fso content"
log.writeline s
This works when being triggered by the task scheduler via cscript.exe.
I will try to modify to log what's happening around the call to the excel file.
/edit3:
Debugging showed that this
Set xlBook = xlApp.Workbooks.Open("D:\xyz\excel.xlsm")
never happens. I put out error numbers and got error 1004 for this call. Still not sure what's the issue, but at least I got an error number now.
/edit4:
error 1004 when trying to run this as a scheduled tasks persists. When I am running it by double clicking the .vbs, everything works.
The key was to create both these folders:
C:\Windows\System32\config\systemprofile\Desktop
and
C:\Windows\SysWOW64\config\systemprofile\Desktop
Excel apparently has troubles running in non-interactive mode when these folders are not present (not sure why). Creating them got rid ofthe 1004 error when opening the workbook via vbs.

VBscript Unable to Run Shell Command

I have set up the following Sub to run shell commands quickly and easily.
This script works for the login scripts at my company without fail.
I am currently developing a script to add a large batch of users to our domain.
When I used this Sub in my new script I receive an error saying that the file cannot be found.
I have tried using the fix in this stackoverflow post, but I recieve the same error even with this code.
VBScript WScript.Shell Run() - The system cannot find the file specified
The part I find puzzling is that this sub works just fine when run from the netlogon folder of our domain controller.
What am I doing wrong?
Thanks,
Sub runcommand(strCommand)
Dim objWshShell, intRC
set objWshShell = WScript.CreateObject("WScript.Shell")
intRC = objWshShell.Run(strCommand, 0, TRUE)
call reportError(intRC,strCommand)
set objWshShell = nothing
end Sub
function reportError(intRC, command)
if intRC <> 0 then
WScript.Echo "Error Code: " & intRC
WScript.Echo "Command: " & command
end if
end function
The previous values for strCommand had no spaces and were very straightforward. Your new script is passing more complex variables to your Sub so you need additional conditional handling, as Alex K. pointed out in his Collusion (i.e., "Comment/Solution") above. Alex K.'s sample above is perfect, so, being a Point Pimp tonight, will post it as the solution:
objWshShell.Run("cmd /k echo Hello World", 1, TRUE)

VBScript Writing to Server Text File

I have created a VBScript which pulls the service tag, username, and computer name from a computer. What I need to do now is compile this information in a text document.
How it's set up is as follows:
We have an Active Directory Server, with a folder for login scripts. I have created a batch file to run this .vbs script, and the script works well so far. What I now need is for a file on the AD server, called "logging.txt", to be populated with the information that is created with the .vbs script.
This is the script I have so far:
'Get Dell Service Tag Info
set ProSet = GetObject("winmgmts:").InstancesOf("Win32_BIOS")
Set ProSet1 = GetObject("winmgmts:").InstancesOf("Win32_SystemEnclosure")
For each Pro in ProSet
For each Pro1 in ProSet1
ServiceTag=Pro.SerialNumber
wscript.echo ServiceTag
exit for
Next
exit for
Next
'get username and computername, could also be asked in a batch
Set oShell = WScript.CreateObject("WScript.Shell")
Set oShellEnv = oShell.Environment("Process")
sComputerName = oShellEnv("ComputerName")
sUsername = oShellEnv("username")
wscript.echo sComputerName & " " & sUsername
Thank you very much in advance!
This is what I've tried so far:
sub log (user, computer)
dim fs,f
set fs=Server.CreateObject("Scripting.FileSystemObject")
set f=fs.OpenTextFile(Server.MapPath(".\logging.csv"),8,true)
f.WriteLine now & "," & user & "," & computer
f.Close:set f=Nothing
set fs=Nothing
end sub
I feel as though you're leaving something out.. this is how to write a text file in VBS.
dim filesys, filetxt, getname, path
Set filesys = CreateObject("Scripting.FileSystemObject")
Set filetxt = filesys.CreateTextFile("c:\somefile.txt", True)
path = filesys.GetAbsolutePathName("c:\somefile.txt")
getname = filesys.GetFileName(path)
filetxt.WriteLine("Your text goes here.")
filetxt.Close
If filesys.FileExists(path) Then
Response.Write ("Your file, '" & getname & "', has been created.")
End If
It would probably be easiest to save the information to a local text file and upload it with the command line ftp utility from the batch script that calls your script rather than trying to invent another wheel and do it in vbscript.
You can list the command line options of ftp with:
ftp /?
I recommend setting up something like this:
ftp -s:control.txt
control.txt would contain something like:
open [hostname or address]
[username]
[password]
cd [remote directory name]
put logging.txt
disconnect
bye

Resources