What I'm trying to accomplish is searching multiple computers for event code 41 (unexpected shutdown) in the windows system log, then write that into an excel file for each instance for each computer.
I receive no errors, but nothing is ever written into the excel file. I set up an echo to make sure it was reaching the correct part of the loop (it does!) and I set a literal entry to see if there was an error with the variables (it didn't write). At this point, I'm at a loss.
' https://technet.microsoft.com/library/ee176684.aspx
' http://blogs.technet.com/b/heyscriptingguy/archive/2009/04/06/how-can-i-check-my-event-logs.aspx
' http://stackoverflow.com/questions/21738159/extracting-error-logs-from-windows-event-viewer
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open("H:\Chris Created Stuffs\Windows Stuffs\check_error_41.xlsx")
objExcel.Visible = False
i = 1
x = 0
'On error resume next
'This is the code that will read the computer names off of the
'appropriate spreadhseet
Do Until objExcel.Cells(i, 1).Value = ""
ReDim Preserve strPC(x)
strPC(x) = objExcel.Cells(i, 1).Value
i = i + 1
x = x + 1
Loop
'And this is the code that will write the success or failure
'data in the Excel spreadsheet
Set objSheet1 = objWorkbook.sheets("Missed")
Set objSheet2 = objWorkbook.sheets("Sheet1")
'Set objSheet1 = objExcel.ActiveWorkbook.Worksheets(1)
'Set objSheet2 = objExcel.ActiveWorkbook.Worksheets(2)
f = 1
m = 1
'Set obj = CreateObject("Scripting.FileSystemObject")
For Each strPC In strPC
Set objWMIService = GetObject("winmgmts:\\" & strPC & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_NTLogEvent WHERE LogFile='System'")
If Err.Number <> 0 Then
'objSheet1.Add
objSheet1.Cells(f, 1).Value = strPC
objSheet1.Cells(f, 2).Value = err.number
f = f + 1
Err.clear
Else
For Each objEvent in colItems
If objEvent.EventCode = 41 Then
'writeLog "Event Code: " & objEvent.EventCode
'writeLog "Event Identifier: " & objEvent.EventIdentifier
'writeLog "Logfile: " & objEvent.Logfile
'writeLog "Message: " & objEvent.Message
'writeLog "Record Number: " & objEvent.RecordNumber
'writeLog "Source Name: " & objEvent.SourceName
'writeLog "Time Generated: " & objEvent.TimeGenerated
'writeLog "Time Written: " & objEvent.TimeWritten
'objSheet2.Add
objSheet2.Cells(m,1).Value = strPC
objSheet2.Cells(m,2).Value = objEvent.EventCode
objSheet2.Cells(m,3).Value = objEvent.EventIdentifier
objSheet2.Cells(m,4).Value = objEvent.Logfile
objSheet2.Cells(m,5).Value = objEvent.Message
objSheet2.Cells(m,6).Value = objEvent.RecordNumber
objSheet2.Cells(m,7).Value = objEvent.SourceName
objSheet2.Cells(m,8).Value = objEvent.TimeGenerated
objSheet2.Cells(m,9).Value = objEvent.TimeWritten
objSheet2.Cells(m,10).Value = "Listen!"
m = m + 1
wscript.echo "We Got One!!!!"
Else
m = m + 1
End If
Next
Err.clear
End If
Next
objExcel.ActiveWorkbook.Save
objExcel.Quit
wscript.echo "Done"
I think your primary problem was ignoring the Workbook Object and Worksheet Object. In this code:
Do Until objExcel.Cells(i, 1).Value = ""
ReDim Preserve strPC(x)
strPC(x) = objExcel.Cells(i, 1).Value
i = i + 1
x = x + 1
Loop
Nothing is actually being pulled from the worksheet. I've had to guess a little as to the actual origin but the syntax is correct; you may have to make specific adjustments to your own worksheet layout.
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True 'False
Set objWorkbook = objExcel.Workbooks.Open("H:\Chris Created Stuffs\Windows Stuffs\check_error_41.xlsx")
i = 1
x = 0
'On error resume next
'This is the code that will read the computer names off of the appropriate spreadhseet
Do Until objWorkbook.Worksheets(1).Cells(i, 1).Value = ""
ReDim Preserve strPCs(x)
strPCs(x) = objWorkbook.Worksheets(1).Cells(i, 1).Value
'msgbox objWorkbook.Worksheets(1).Cells(i, 1).Value
i = i + 1
x = x + 1
Loop
'And this is the code that will write the success or failure data in the Excel spreadsheet
Set objSheet1 = objWorkbook.Worksheets("Missed")
Set objSheet2 = objWorkbook.Worksheets("Sheet1")
f = 1
m = 1
For Each strPC In strPCs
Set objWMIService = GetObject("winmgmts:\\" & strPC & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_NTLogEvent WHERE LogFile='System'")
If Err.Number <> 0 Then
'objSheet1.Add
objSheet1.Cells(f, 1).Value = strPC
objSheet1.Cells(f, 2).Value = err.number
f = f + 1
Err.clear
Else
For Each objEvent in colItems
If objEvent.EventCode = 41 Then
'writeLog "Event Code: " & objEvent.EventCode
'writeLog "Event Identifier: " & objEvent.EventIdentifier
'writeLog "Logfile: " & objEvent.Logfile
'writeLog "Message: " & objEvent.Message
'writeLog "Record Number: " & objEvent.RecordNumber
'writeLog "Source Name: " & objEvent.SourceName
'writeLog "Time Generated: " & objEvent.TimeGenerated
'writeLog "Time Written: " & objEvent.TimeWritten
'objSheet2.Add
objSheet2.Cells(m, 1).Value = strPC
objSheet2.Cells(m, 2).Value = objEvent.EventCode
objSheet2.Cells(m, 3).Value = objEvent.EventIdentifier
objSheet2.Cells(m, 4).Value = objEvent.Logfile
objSheet2.Cells(m, 5).Value = objEvent.Message
objSheet2.Cells(m, 6).Value = objEvent.RecordNumber
objSheet2.Cells(m, 7).Value = objEvent.SourceName
objSheet2.Cells(m, 8).Value = objEvent.TimeGenerated
objSheet2.Cells(m, 9).Value = objEvent.TimeWritten
objSheet2.Cells(m, 10).Value = "Listen!"
m = m + 1
'wscript.echo "We Got One!!!!"
'do not add to m on no-write; it only creates blank rows
End If
Next
Err.clear
End If
Next
'objWorkbook.Close True
'objExcel.Quit
wscript.echo "Done"
I've commented out the code lines to make the Excel application object hidden as to save asn close it in order that you can observe the process. Uncomment them once you are happy with the process.
Related
I have written a quite complex VBA script to run on a Word document to
transform it into an email body (together with a bunch of other documents),
combine it with other documents and save as pdf-attachment,
open email-distribution lists
create outlook items and put the distribution lists into a bcc field and body from earlier document
The script worked quite fine until it stopped for unclear to me reason. A "Run-time error '1001': Method 'Range' of object '_Global' failed." started to occur in the "Step 3 ...", specifically in the second line:
objLista.Worksheets(1).Activate
last_row = Range("A1").End(xlDown).Row
The script activates the worksheet just fine, but fails to do anything else with it. I tried to use explicit names of the workbook and worksheet in question, but it didn't help. The same lines in different yet similar script still work well. So I find it hard to find the source of the problem and correct it. I use MS Windows 10, and Office 365.
The whole script below:
Sub script()
' >>>>>>>>>>>>>>>>>>>>>>> Step 0. Declaration of variables and paths <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Dim Disclaimer_Path As String
Dim Email_Path As String
Dim objOutlook As Object
Dim objMail As Object
Dim ExcelApp As Excel.Application
Dim objLista As Workbook
Dim Today As String
Today = Format(Date, "yyyymmdd")
Disclaimer_Path = ...
Email_Path = "!_email.docx"
Distribution_list_Path = "!_List.xlsm"
Distribution_list_Path = "!_List_2.xlsm"
Pdf_Path = ...
Set objOutlook = CreateObject("Outlook.Application")
Set ExcelApp = New Excel.Application
' >>>>>>>>>>>>>>>>>>>>>>> Step 1. Creating e-mail body <<<<<<<<<<<<<<<<<<<<<<<<<<<
' First creating an email-body
Documents.Open FileName:=ActiveDocument.Path & "\1_News.docx"
Documents.Open FileName:=ActiveDocument.Path & "\2_Essay.docx"
Documents.Open FileName:=ActiveDocument.Path & "\3_Comment.docx"
Documents.Open FileName:=Disclaimer_Path
Documents.Open FileName:=Email_Path
Documents("1_News.docx").Activate
Selection.WholeStory
Selection.Copy
Documents("!_Email.docx").Activate
With Selection
.MoveDown
.MoveDown
.PasteAndFormat wdPasteDefault
End With
Documents("2_Essay.docx").Activate
Selection.WholeStory
Selection.Copy
Documents("!_Email.docx").Activate
Selection.PasteAndFormat wdPasteDefault
Documents("3_Comment.docx").Activate
Selection.WholeStory
Selection.Copy
Documents("!_Email.docx").Activate
With Selection
.PasteAndFormat wdPasteDefault
.WholeStory
End With
' Cleaning
Documents("2_Essay.docx").Close SaveChanges:=wdDoNotSaveChanges
Documents("3_Comment.docx").Close SaveChanges:=wdDoNotSaveChanges
Documents("Disclaimer.docx").Close SaveChanges:=wdDoNotSaveChanges
Stop
' >>>>>>>>>>>>>>>>>>>>>>>>>>>>> Step 2. Creation of pdf <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Documents("1_News.docx").Activate
Selection.WholeStory
Selection.Copy
ThisDocument.Activate
With Selection
'.Range.Text = vbNewLine
.MoveDown
.PasteAndFormat wdPasteDefault
.Range.Text = vbNewLine
.MoveDown
End With
ActiveDocument.ActiveWindow.View.Type = wdMasterView
With ActiveDocument.Subdocuments
.AddFromFile Name:=ActiveDocument.Path & "\2_Essay.docx"
.AddFromFile Name:=ActiveDocument.Path & "\3_Comment.docx"
.AddFromFile Name:=ActiveDocument.Path & "\4_Preview.docx"
.AddFromFile Name:=ActiveDocument.Path & "\5_Comment_2.docx"
.AddFromFile Name:=ActiveDocument.Path & "\8_Calendar.docx"
.AddFromFile Name:=Disclaimer_Path
End With
'Returns to standard view
ActiveDocument.ActiveWindow.View.Type = wdPrintView
Selection.HomeKey Unit:=wdStory
Stop
ActiveDocument.ExportAsFixedFormat Pdf_Path, wdExportFormatPDF
' >>>>>>>>>>>>>>>>>>>>>>>> Step 3. Creating Distribution lists <<<<<<<<<<<<<<<<<<<<<<<<<<<<
Set objLista = ExcelApp.Workbooks.Open(Distribution_list_Path)
ExcelApp.Visible = True
Dim lista_1 As String, lista_2 As String, lista_3 As String, lista_4 As String, lista_5 As String, lista_6 As String, lista_7 As String, lista_8 As String, lista_9 As String
lista_1 = ""
lista_2 = ""
lista_3 = ""
lista_4 = ""
lista_5 = ""
lista_6 = ""
lista_7 = ""
lista_8 = ""
lista_9 = ""
objLista.Worksheets(1).Activate
last_row = Range("A1").End(xlDown).Row
For i = 1 To last_row
lista_1 = lista_1 & "; " & Cells(i, 1).Value
Next i
objLista.Worksheets(2).Activate
last_row = Range("A1").End(xlDown).Row
For i = 1 To last_row
lista_2 = lista_2 & "; " & Cells(i, 1).Value
Next i
objLista.Worksheets(3).Activate
last_row = Range("A1").End(xlDown).Row
For i = 1 To last_row
lista_3 = lista_3 & "; " & Cells(i, 1).Value
Next i
objLista.Worksheets(4).Activate
last_row = Range("A1").End(xlDown).Row
For i = 1 To last_row
lista_4 = lista_4 & "; " & Cells(i, 1).Value
Next i
objLista.Worksheets(5).Activate
last_row = Range("A1").End(xlDown).Row
For i = 1 To last_row
lista_5 = lista_5 & "; " & Cells(i, 1).Value
Next i
objLista.Worksheets(6).Activate
last_row = Range("A1").End(xlDown).Row
For i = 1 To last_row
lista_6 = lista_6 & "; " & Cells(i, 1).Value
Next i
' Now differentr set of lists
Set objLista_2 = ExcelApp.Workbooks.Open(Distribution_list_Path_2)
objLista_2.Worksheets(1).Activate
last_row = Range("A1").End(xlDown).Row
For i = 1 To last_row
lista_7 = lista_7 & "; " & Cells(i, 1).Value
Next i
objLista_2.Worksheets(2).Activate
last_row = Range("A1").End(xlDown).Row
For i = 1 To last_row
lista_8 = lista_8 & "; " & Cells(i, 1).Value
Next i
objLista_2.Worksheets(3).Activate
last_row = Range("A1").End(xlDown).Row
For i = 1 To last_row
lista_9 = lista_9 & "; " & Cells(i, 1).Value
Next i
' >>>>>>>>>>>>>>>>>>>>>>>>>>>>> Step 4. Creates e-mails <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Documents("!_Email.docx").Activate
Selection.Copy
For Each Item In Array(lista_1, lista_2, lista_3, lista_4, lista_5, lista_6, lista_7, lista_8, lista_9)
With objOutlook.CreateItem(0)
oAccount = ""
.bcc = Item
.Subject = "Weekly"
.Attachments.add Pdf_Path
Set Editor = .GetInspector.WordEditor
Editor.Content.Paste
.Display
End With
Next Item
'Cleaning
Documents("1_News.docx").Close SaveChanges:=wdDoNotSaveChanges
Documents("!_email.docx").Close SaveChanges:=wdDoNotSaveChanges
Workbooks("!_List.xlsm").Worksheets("List_1").Activate
Range("A1").Select 'To żeby uniknąć jednego z błędów, który się wcześniej wywalał, gdy arkusz był zamykany z kursorem w innym miejscu niż "A1"
Workbooks("!_List.xlsm").Close SaveChanges:=wdDoNotSaveChanges
Workbooks("!_List_2.xlsm").Worksheets(1).Activate
Range("A1").Select 'To żeby uniknąć jednego z błędów, który się wcześniej wywalał, gdy arkusz był zamykany z kursorem w innym miejscu niż "A1"
Workbooks("!_List_2.xlsm").Close SaveChanges:=wdDoNotSaveChanges
End Sub
I know there's additional stuff in the Declarations, it's for other macros I've written.
I've several calendars. I've a spreadsheet where I paste information about a site, and I've buttons that generate appointments and emails.
I've code to set an appointment, however it goes to my main calendar. I'm trying to get the appointment onto my other calendars. I've read about MAPI functions, but can't get it to work. The location is \myemail#me.com\Calendar. Name of the calendar is SVN Calendar.
Dim olApp As Outlook.Application9
Dim olEmail As Outlook.MailItem
Dim olCal As Outlook.AppointmentItem
Dim olFolder As Outlook.Folder
Dim RequiredAttendee, OptionalAttendee, ResourceAttendee As Outlook.Recipient
Dim rtf() As Byte
Dim rngTo As Range
Dim rngCC As Range
Dim rngSUB As Range
Dim rngCALloc As Range
Dim rngCALstart As Range
Dim rngCALend As Range
Dim rngBody As Range
Dim myItem As Object
Sub newTestCreateCalendarUSA1()
'Testing calendar to other calendar than main.
' i.e. SVN Calendar. can't identify the actual calendar.
Set olApp = New Outlook.Application
Set m = olApp.CreateItem(olMailItem)
Set appt = olApp.CreateItem(olAppointmentItem)
With ActiveSheet
Set rngCC = .Range("I34")
Set rngCALloc = .Range("I5")
Set rngCALstart = .Range("I11")
Set rngCALend = .Range("I12")
Set rngSUB = .Range("I33")
Set rngSite = .Range("C2")
Set rngLoc = .Range("C4")
Set rngTYPE = .Range("B23")
Set rngGON = .Range("C23")
Set rngPurpose = .Range("C21")
Set rngGoals = .Range("C22")
Set rngDate = .Range("I1")
Set rngDateStart = .Range("I8")
Set rngDateEnd = .Range("I9")
Set rngTime = .Range("I10")
Set rngCAS = .Range("C26")
End With
MsgBox "Ensure all attendees are correct prior to sending invite."
appt.MeetingStatus = olMeeting
appt.RequiredAttendees = rngCC.Value
appt.Subject = rngSUB.Value
appt.Location = rngCALloc.Value
appt.Start = rngCALstart.Value
appt.End = rngCALend.Value
appt.AllDayEvent = True
m.BodyFormat = olFormatHTML
m.HTMLBody = Range("I31").Value
m.GetInspector().WordEditor.Range.FormattedText.Copy
appt.GetInspector().WordEditor.Range.FormattedText.Paste
appt.Display
m.Close False
End Sub
Edit: Thanks for directing me to follow the folder tree. I tried understanding the GetNameSpace thing, but couldn't get it to work.
I did find a different code and got it to make an appointment on the correct calendar.
Sub SVN_Calendar_Invite()
'trial run of SVN Calendar with other code
Dim oApp As Object
Dim oNameSpace As Namespace
Dim oFolder As Object
Set oApp = New Outlook.Application
Set oNameSpace = oApp.GetNamespace("MAPI")
Set oFolder = oNameSpace.GetFolderFromID("0000000098F32312526B334EAEC97D94705E33FB0100C964D8D325E3554DA24A72FB876E3F600001912394000000")
With ActiveSheet
Set rngCC = .Range("I34")
Set rngCALloc = .Range("I5")
Set rngCALstart = .Range("I11")
Set rngCALend = .Range("I12")
Set rngSUB = .Range("I33")
Set rngSite = .Range("C2")
Set rngLoc = .Range("C4")
Set rngTYPE = .Range("B23")
Set rngGON = .Range("C23")
Set rngPurpose = .Range("C21")
Set rngGoals = .Range("C22")
Set rngDate = .Range("I1")
Set rngDateStart = .Range("I8")
Set rngDateEnd = .Range("I9")
Set rngTime = .Range("I10")
Set rngCAS = .Range("C26")
End With
With oFolder
Set olApt = oApp.CreateItem(olAppointmentItem)
With olApt
.AllDayEvent = True
.RequiredAttendees = rngCC.Value
.Start = rngDateStart.Value
.End = rngDateEnd.Value
.Subject = rngSUB.Value
.Location = rngLoc.Value
.Body = "The body of your appointment note"
.BusyStatus = olFree
.Save
.Move oFolder
End With
Set olNS = Nothing
Set olApp = Nothing
Set olApt = Nothing
End With
End Sub
I've these problems now.
1- if I use .Display to bring up the calendar item to review it, it doesn't display.
2- even though it's an all day event, and the cells are 3 days apart, it subtracts the end date by 1 day.
3- I have to manually invite the attendees, which defeats the purpose of doing this invite.
ok so im about two years late. found this thread while i was facing the same problem. manage to solve with some trial and error so, this works for me.
so you might give it a try for future pple who are googling for the same ans...
a lil more info is i did not set reference to Outlook under tools cos i have many user files.
'start
'break down here retype cos stackoverflow format xxx
Sub Add_Appt_to_Main_Sub_Calendar()
Dim BOOK2 As Workbook
Workbooks.Open Filename:= _
"Name of your file.csv"
'csv is readable by outlook but not excel, u need to change the file type first
'start pulling data from your csv file here
'if you are not setting reference to outlook under tools, please define all your outlook names as Object
Dim olAppts As Object
Dim Calfolder As Object
'this to define the main calendar folder
Dim Subfolder As Object
'this to define the sub calendar folder
Set olApp = CreateObject("Outlook.Application")
Set olNamespace = olApp.GetNamespace("MAPI")
Dim filter As Variant
'cos we dont want to keep import duplicate appt into outlook calendar so we need to create and define a filter
Dim olfolder As Object
'the folder picker by user
Dim strolFolder As String
' we want to get the name of the folder picker by user
Set olfolder = olApp.GetNamespace("MAPI").Pickfolder
'olfolder.Display
'how to find the name of the folder selected
On Error Resume Next
If olfolder = "" Then
MsgBox "No calendar selected."
Workbooks("Name of your file.csv").Close savechanges:=True
'close the csv file if no calendar selected by user
Exit Sub
Else
strolFolder = olfolder
'name of the file pick by user
Set Calfolder = olNamespace.GetDefaultFolder(9)
'defaultfolder(9) is the main calendar by default tagged to user outlook acc
strCalfolder = Calfolder
'name of the sub folder
MsgBox strolFolder
MsgBox strCalfolder
MsgBox (olfolder.folderpath)
MsgBox (Calfolder.folderpath)
'keep for debugging
If olfolder.folderpath <> Calfolder.folderpath Then
'this is the line that add appointment into sub calendar
Set olAppts = olNamespace.GetDefaultFolder(9).Folders(strolFolder)
'eg. Set olAppts = olNamespace.GetDefaultFolder(9).Folders("name of subfolder")
'this is the main folder
Set Calfolder = olNamespace.GetDefaultFolder(9)
'MsgBox Calfolder
'this is the sub folder i want to add in
Set Subfolder = Calfolder.Folders(strolFolder)
'MsgBox Subfolder
'add appt to subfolder
Set olAppt = Subfolder.items.Add
'MsgBox (olfolder.EntryID)
'MsgBox (olfolder)
'MsgBox (olfolder.FolderPath)
'keep for debugging
r = 2
Do Until Trim(Cells(r, 1).Value) = ""
'filter by subject, start date and location
'filter = "[Subject] = '" & Cells(r, 2).Value & "' and [Start] = '" & Format(Cells(r, 7).Value, "ddddd Hh:Nn") & "' and [Location] = '" & Cells(r, 8).Value & "'"
'filter = "[Subject] = '" & Replace(Cells(r, 2).Value, "'", "''") & "' and [Start] = '" & Format(Cells(r, 7).Value, "dddd Hn:Hn") & "' and [Location] = '" & Replace(Cells(r, 8).Value, "'", "''") & "'"
'On Error Resume Next 'enable error-handling machine
filter = "[Subject] = '" & Cells(r, 2).Value & "' and [Start] = '" & Format(Cells(r, 7).Value, "ddddd Hh:Nn") & "' and [Location] = '" & Cells(r, 8).Value & "'"
filter = "[Subject] = '" & Cells(r, 2).Value & "' and [Start] = '" & Format(Cells(r, 7).Value, "ddddd Hh:Nn") & "' and [Location] = '" & Replace(Cells(r, 8).Value, "'", "''") & "'"
'Set olAppt = olAppts.items.Find(filter)
'currently this does a check in your main calendar
'if existing appointment based on subject, start date and location is not found, add appointment
' i need to do a search in the subcalendar instead of main calendar
Set olAppt = olAppts.items.Find(filter)
If TypeName(olAppt) = "Nothing" Then
Set myAppt = Subfolder.items.Add
'Set myAppt = olApp.CreateItem(1)
'if using main use create, if use subfolder add
myAppt.Subject = Cells(r, 2).Value
myAppt.Location = Cells(r, 8).Value
myAppt.Start = Cells(r, 7).Value
myAppt.Categories = Cells(r, 3).Value
myAppt.Duration = 120
myAppt.BusyStatus = 2
myAppt.ReminderSet = True
myAppt.Body = Cells(r, 11).Value
myAppt.Save
End If
r = r + 1
Loop
MsgBox "TCU added to sub calendar."
'if picked folder is sub calendar
Else
Set olApp = CreateObject("Outlook.Application")
strCalfolder = olNamespace.GetDefaultFolder(9)
Set olNamespace = olApp.GetNamespace("MAPI")
Set olAppts = olNamespace.GetDefaultFolder(9)
r = 2
Do Until Trim(Cells(r, 1).Value) = ""
'filter by subject, start date and location
'filter = "[Subject] = '" & Cells(r, 2).Value & "' and [Start] = '" & Format(Cells(r, 7).Value, "ddddd Hh:Nn") & "' and [Location] = '" & Cells(r, 8).Value & "'"
'filter = "[Subject] = '" & Replace(Cells(r, 2).Value, "'", "''") & "' and [Start] = '" & Format(Cells(r, 7).Value, "dddd Hn:Hn") & "' and [Location] = '" & Replace(Cells(r, 8).Value, "'", "''") & "'"
On Error Resume Next 'enable error-handling machine
filter = "[Subject] = '" & Cells(r, 2).Value & "' and [Start] = '" & Format(Cells(r, 7).Value, "ddddd Hh:Nn") & "' and [Location] = '" & Cells(r, 8).Value & "'"
filter = "[Subject] = '" & Cells(r, 2).Value & "' and [Start] = '" & Format(Cells(r, 7).Value, "ddddd Hh:Nn") & "' and [Location] = '" & Replace(Cells(r, 8).Value, "'", "''") & "'"
Set olAppt = olAppts.items.Find(filter)
'if existing appointment not found, add appointment
If TypeName(olAppt) = "Nothing" Then
Set myAppt = olApp.CreateItem(1)
myAppt.Subject = Cells(r, 2).Value
myAppt.Location = Cells(r, 8).Value
myAppt.Start = Cells(r, 7).Value
myAppt.Categories = Cells(r, 3).Value
myAppt.Duration = 120
myAppt.BusyStatus = 2
myAppt.ReminderSet = True
myAppt.Body = Cells(r, 11).Value
myAppt.Save
End If
r = r + 1
Loop
MsgBox "TCU added to main calendar."
End If
End If
'end add appt
'close ur csv file
Workbooks("Name of your file.csv").Close savechanges:=True
End Sub
So I have this Auto Email Script, it all works fine but the problem I am having is that when an email pops up that isn't valid it will error out and quit, what I am wondering is, is there a way to tell it if there is an error skip that record and move onto the next one?
Set objMessage = CreateObject("CDO.Message")
Set app = CreateObject("Excel.Application")
Set fso = CreateObject("Scripting.FileSystemObject")
For Each f In fso.GetFolder("##############").Files
If LCase(fso.GetExtensionName(f)) = "xls" Then
Set wb = app.Workbooks.Open(f.Path)
set sh = wb.Sheets("Auto Email Script")
row = 4
email = sh.Range("A" & row)
LastRow = sh.UsedRange.Rows.Count
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim f
Set f = fso.OpenTextFile("#####################.txt", ForReading)
BodyText = f.ReadAll
For r = row to LastRow
If App.WorkSheetFunction.CountA(sh.Rows(r)) <> 0 Then
email = sh.Range("A" & row)
sh.Range("I" & row).Value = "Sent"
row = row + 1
End if
If email = "" Then
Wscript.Quit
End if
objMessage.Subject = "Billing: Meter Read"
objMessage.From = "################"
objMessage.To = email
objMessage.TextBody = BodyText
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "################"
objMessage.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objMessage.Configuration.Fields.Update
objMessage.Send
Next
wb.Save
f.Close
Set f = Nothing
Set fso = Nothing
wb.Close
End If
Next
It's still not clear to me what you mean by "invalid address". If you mean a malformed address you could validate it e.g. with a regular expression:
Set re = New RegExp
re.Pattern = "^[a-z0-9][a-z0-9._]*#[a-z][a-z0-9-]*\.[a-z]+$"
re.IgnoreCase = True
If re.Test(email) Then
'send mail
End If
Note that the expression above is rather conservative and covers only a safe subset of all potentially valid addresses.
If you mean that an address is rejected by your mail server you need to enable error handling for objMessage.Send as #mehow suggested:
On Error Resume Next
objMessage.Send
If Err Then WScript.Echo Hex(Err.Number) & ": " & Err.Description
On Error Goto 0
I am trying to create a VB Script which will produce an Excel based report on the disk space for the servers within my environment. I have 3 hurdles left which I can't get over.
How can I left align all of the columns/cells within the worksheet? Line 25 is where I have tried to do this however it throws the error, "Unable to set the HorizontalAlignment property of the Range class".
Some servers have more than 1 drive (eg C, D, E). When the script produces the report, it will only show the last drive (eg E). How can I make it show every drive for each server?
When I run the script, I would like it to append the report with the current day's disk usage. At the moment, it will replace the existing cells with the current day's disk usage.
The code for my script is as follows:
On Error Resume Next
Const ForReading = 1
Const HARD_DISK = 3
x = 1
dtmDate = Date
strDay = Day(Date)
strMonth = Month(Date)
strYear = Right(Year(Date), 2)
strFileName = "C:\Users\cvandal\Desktop\Scripts\Server_Disk_Space_Report.xlsx"
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists("C:\Users\cvandal\Desktop\Scripts\Server_Disk_Space_Report.xlsx") Then
Set serverList = objFSO.OpenTextFile("servers.txt", ForReading)
Set objExcel = CreateObject("Excel.Application")
objExcel.Workbooks.Open "C:\Users\cvandal\Desktop\Scripts\Server_Disk_Space_Report.xlsx"
objExcel.Visible = True
objExcel.Columns("A:ZZ").ColumnWidth = 25
objExcel.Columns("A:ZZ").HorizontalAlignment = xlHAlignLeft
objExcel.Cells(2, 1).Value = "Server Disk Space Report"
objExcel.Cells(4, 1).Value = dtmDate
objExcel.Cells(5, 1).Value = "Drives:"
objExcel.Cells(6, 1).Value = "Total Capacity (in GB):"
objExcel.Cells(7, 1).Value = "Used Capacity (in GB):"
objExcel.Cells(8, 1).Value = "Free Space (in GB):"
objExcel.Cells(9, 1).Value = "Free Space (in %):"
Do Until serverList.AtEndOfStream
x = x + 1
strComputer = serverList.ReadLine
Set objWMIService = GetObject("winmgmts:{impersonationlevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE DriveType = " & HARD_DISK & "")
If Err.Number <> 0 Then
'WScript.Echo "Error: " & Err.Number
'WScript.Echo "Error (Hex): " & Hex(Err.Number)
'WScript.Echo "Source: " & Err.Source
'WScript.Echo "Description: " & Err.Description
objExcel.Cells(4, x).Value = strComputer & " - " & Err.Description
objExcel.Cells(4, x).Columns.AutoFit
Err.Clear
Else
For Each objDisk in colDisks
drives = "Error"
totalCapacity = 0
freeSpace1 = 0
usedCapacity = 0
freeSpace2 = 0
drives = objDisk.DeviceID
totalCapacity = Round((objDisk.Size / 1073741824), 2)
freeSpace1 = Round((objDisk.FreeSpace / 1073741824), 2)
usedCapacity = Round((totalCapacity - freeSpace1), 2)
freeSpace2 = Round((freeSpace1 / totalCapacity)*100, 0)
If freeSpace2 > 20 Then
objExcel.Cells(4, x).Value = strComputer
objExcel.Cells(5, x).Value = drives
objExcel.Cells(6, x).Value = totalCapacity & " GB"
objExcel.Cells(7, x).Value = usedCapacity & " GB"
objExcel.Cells(8, x).Value = freeSpace1 & " GB"
objExcel.Cells(9, x).Value = freeSpace2 & "%"
objExcel.Cells(9, x).Interior.Color = RGB(198,239,206)
ElseIf freeSpace2 < 10 Then
objExcel.Cells(4, x).Value = strComputer
objExcel.Cells(5, x).Value = drives
objExcel.Cells(6, x).Value = totalCapacity & " GB"
objExcel.Cells(7, x).Value = usedCapacity & " GB"
objExcel.Cells(8, x).Value = freeSpace1 & " GB"
objExcel.Cells(9, x).Value = freeSpace2 & "%"
objExcel.Cells(9, x).Interior.Color = RGB(255,199,206)
Else
objExcel.Cells(4, x).Value = strComputer
objExcel.Cells(5, x).Value = drives
objExcel.Cells(6, x).Value = totalCapacity & " GB"
objExcel.Cells(7, x).Value = usedCapacity & " GB"
objExcel.Cells(8, x).Value = freeSpace1 & " GB"
objExcel.Cells(9, x).Value = freeSpace2 & "%"
objExcel.Cells(9, x).Interior.Color = RGB(255,235,156)
End If
Next
End If
Loop
Else
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = False
Set objWorkbook = objExcel.Workbooks.Add()
objWorkbook.SaveAs(strFileName)
objExcel.Quit
WScript.Echo "Server_Disk_Space_Report.xlsx has been created. Please re-run the script."
End If
It doesn't look like you've defined a constant for the value of xlHAlignLeft.
You should increment the counter x inside of your disk loop:
For Each objDisk in colDisks
x = x + 1 ' <-- add this line
You'll probably have to play with where exactly in the code you increment the counter, depending on how you want the output to look. I think the place I put it in my example would result in a blank line between each machine.
The trick here is to initialize x to the first available row, instead of always defaulting to 1. The following code searches the first column ('A') for the last non-empty row. (reference)
Const xlUp = -4162
x = objExcel.Cells(Rows.Count, 1).End(xlUp).Row
Did you know that you can put the markup for HTML tables into a .xls file and open it with Excel? It even works for Excel 2000! Try it, and you'll be so much happier that you don't have to create the "Excel.Application" COM object!
I'm trying to add a list of users from a xls file and I get this error:
Line: 6
Char: 5
Invalid Syntax
The script I'm trying to use looks like this:
Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open _
("C:\Scriptt/Users.xls")
intRow = 3
Do Until objExcel.Cells(intRow,1).Value = ""
Set objOU = GetObject("ou=REAL, dc=ormbunken, dc=com")
Set objUser = objOU.Create _
("User", "cn=" & objExcel.Cells(intRow, 2).Value)
objUser.sAMAccountName = objExcel.Cells(intRow, 1).Value
objUser.SetPassword = objExcel.Cells(intRow, 5).Value
objUser.GivenName = objExcel.Cells(intRow, 3).Value
objUser.SN = objExcel.Cells(intRow, 4).Value
objUser.AccountDisabled = FALSE
objUser.SetInfo
intRow = intRow + 1
Loop
objExcel.Quit
Does anyone know whats wrong?
Do you need to supply a protocol/server in the GetObject call? Like what this says
Set oOU = GetObject("LDAP://test.test.cz/ou=skup,dc=test,dc=test,dc=cz")
Set oUser = oOU.Create("User", "cn=" & "Test" & " " & "Tester")
taken from http://msdn.itags.org/iis/2649/
did a google, found http://www.computerperformance.co.uk/vbscript/vbscript_user_spreadsheet.htm