Select account for VBA script - vba

I have written code to limit the number of addresses for the To, CC and BCC fields.
The only problem is the code affects all accounts and not a specific account which I select.
e.g: user1#xyz.com
user2#xyz.com
I want this code to work only for the "user1#xyz.com" account and not the "user2#xyz.com" account. But the code is running in the whole Outlook session. Is there any option to choose the account in the code?
Private Sub Application_ItemSend(ByVal Element As Object, Cancel As Boolean)
Dim aaa() As String
Dim bbb() As String
Dim ccc() As String
aaa = Split(Element.To, ";")
bbb = Split(Element.CC, ";")
ccc = Split(Element.BCC, ";")
If (UBound(aaa) + 1) + (UBound(bbb) + 1) + (UBound(ccc) + 1) > 10 Then
MsgBox ("You have added too many recipients! Please contact your Administrator."), vbExclamation, "Authorization required!"
Cancel = True
End If
End Sub

I've written a lot of VBA, but none for Outlook, so I'm guessing a bit here. How about inserting this before you Split anything:
If LCase(Environ("Username") & "#" & Environ("Userdnsdomain")) <> "user1#xyz.com" Then Exit Sub
?

You can find the applicable account like this
Private Sub Application_ItemSend(ByVal Element As Object, Cancel As Boolean)
Dim oAccount As account
For Each oAccount In Session.Accounts
If oAccount = "user1#xyz.com" Then
Dim aaa() As String
Dim bbb() As String
Dim ccc() As String
aaa = Split(Element.To, ";")
bbb = Split(Element.CC, ";")
ccc = Split(Element.BCC, ";")
If (UBound(aaa) + 1) + (UBound(bbb) + 1) + (UBound(ccc) + 1) > 1 Then
MsgBox ("You have added too many recipients! Please contact your Administrator."), vbExclamation, "Authorization required!"
Cancel = True
End If
End If
Next
ExitRoutine:
Set oAccount = Nothing
End Sub

Related

Else Box keeps activating but the If solutions are satisfied

Private Sub Dutybox_Change()
Dim Val As String
ThisWorkbook.Worksheets("User Dashboard").Range("L17").Value = Me.Dutybox.Value
Calculate
If Me.ComboBox18.RowSource <> "" And Me.RankCombo.Value <> "" And Me.Exambox.Value <> "" And Me.Dutybox.Value <> "" Then
Me.ComboBox18.RowSource = "=Rate"
Else
MsgBox "Please Select all the above values"
End If
End Sub
So the IF parts are all filled, and it should fill ComboBox18 with =Rate (a named range) but it keeps popping up the Msgbox
Item 1
Private Sub ComboBox18_Change()
Dim Val As String
ThisWorkbook.Worksheets("User Dashboard").Range("L18").Value = Me.ComboBox18.Value
End Sub
Item 2
Private Sub RankCombo_Change()
ThisWorkbook.Worksheets("User Dashboard").Range("L15").Value = Me.RankCombo.Value
End Sub
Item 3
Private Sub Exambox_Change()
Dim Val As String
ThisWorkbook.Worksheets("User Dashboard").Range("L16").Value = Me.Exambox.Value
End Sub
Code to push range to ComboBox18
Private Sub ComboBox18_Intialize()
MsgBox "combo box"
Me.ComboBox18.List = Application.Transpose(Names("Rate").RefersToRange.Value)
End Sub
I can't figure out why Msgbox is populating when the values are satisified.
Thank you in advance
One way to debug this program is to verify the output in Immediate window,
Please break your code at
If Me.ComboBox18.RowSource <> "" And Me.RankCombo.Value <> "" And Me.Exambox.Value <> "" And Me.Dutybox.Value <> "" Then
On immediate window type the following and press enter to verify the conditions
?Me.ComboBox18.RowSource <> ""
?Me.RankCombo.Value <> ""
?Me.Exambox.Value <> ""
?Me.Dutybox.Value <> ""
all the above four condition should return true.
I suspect that your expressions might not properly handle Null values.
Try using Nz() like this: Nz(Me.RankCombo.Value,"") <> ""
You can also add code to check your assessments:
Debug.Print "Combo18", Me.ComboBox18.RowSource <> ""
Debug.Print "Rank", Me.RankCombo.Value <> ""

Passing Values in VBA

In the code I am posting, I am using a check box called "ACDS Test" and whenever it is checked it creates a sheet, then when it becomes unchecked it calls the upper function and deletes the sheet.
I am trying to add a message box that essentially works like a fail safe to ensure they want to delete the page. If they say they do not want to delete the page then I want the checkbox to stay checked.
For some reason I am getting this error message when I try to pass the value to make sure the checkbox stays checked and I cannot figure out why.
The error comes up on the line:
Sub ACDSTest_Click(CorrectValue As Integer)
And the specific error is: "Compile error: Procedure Declaration does not match description of event or procedure having the same name".
Any help is much appreciated! IF any more clarification is needed please feel free to ask!
Sub DeleteWorksheet(NameSheet As String)
Dim Ans As Long
Dim t As String
Dim CorrectValue As Integer
Dim i As Long, k As Long
k = Sheets.Count
Ans = MsgBox("Would you like to take this test off of the form?", vbYesNo)
Select Case Ans
Case vbYes
'Code reads through each page and finds one with corresponding name to string t
'Once it finds the correct page, it deletes it
For i = k To 1 Step -1
t = Sheets(i).Name
If t = NameSheet Then
Sheets(i).Delete
End If
Next i
CorrectValue = 0
Case vbNo
CorrectValue = 1
End Select
End Sub
Sub ACDSTest_Click(CorrectValue As Integer)
Dim NameSheet As String
Dim NameValue As String
NameSheet = "ACDS"
NameValue = "ACDS Test"
If ACDSTest.Value = True Then
CreateWorksheet (NameSheet), (NameValue)
Worksheets("Sheet1").Activate
Else
DeleteWorksheet (NameSheet)
If CorrectValue = 1 Then
ActiveSheet.Shapes("ACDS Test").ControlFormat.Value = 1
End If
End If
End Sub
The issue here is that the CorrectValue variable as you define it in DeleteWorksheet does not exist in the context of the
variable does not exist in context of the ACDSTest_Click subroutine. This is because variables defined within subroutines or functions are local to those functions. To correct this I would convert DeleteWorksheet to a function such as the below.
Further, the event that fires Private Sub ACDSTest_Click() cannot handle passing a value to that function, so changing it to Sub ACDSTest_Click(CorrectValue As Integer) causes an error.
Function DeleteWorksheet(ByVal SheetName As String) As Boolean
On Error GoTo SheetDNE
SheetName = Sheets(SheetName).Name 'Check if sheet exists w/o other objects
On Error GoTo 0
Select Case MsgBox("Would you like to take this test off of the form?", vbYesNo)
Case vbYes
Application.DisplayAlerts = False
Sheets(SheetName).Delete
Application.DisplayAlerts = True
DeleteWorksheet = True
Case Else: DeleteWorksheet = False
End Select
Exit Function 'Exit The Function w/o error
SheetDNE: 'Sheet Does Not Exist
MsgBox "The indicated sheet, " & SheetName & ", does not exist", vbOKOnly
End Function
And
Private Sub ACDSTest_Click()
Dim NameSheet As String
Dim NameValue As String
NameSheet = "ACDS"
NameValue = "ACDS Test"
If ACDSTest.Value = True Then
CreateWorksheet (NameSheet), (NameValue)
Worksheets("Sheet1").Activate
Else
If Not DeleteWorksheet(NameSheet) Then _
ActiveSheet.Shapes("ACDS Test").ControlFormat.Value = 1
End If
End Sub

Finding a date in message body and using it to set a reminder in outlook calendar

Currently I have a macro running on all sent items to check that checks to see if I'm sending the e-mail to a particular customer. If I am, then it checks to see if one of the customer’s requirements for all messages is present which is a 'next update due' if it is not it asks if one is required. See below;
Public Sub application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim addrType
Dim addr
Dim recip
For Each recip In Item.Recipients
If recip.Type = olTo Then
addrType = recip.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x3002001F")
If addrType = "EX" Then
addr = recip.AddressEntry.GetExchangeUser.PrimarySmtpAddress
Else
addr = recip.Address
End If
If LCase(addr) = "relevantemail1#outlook.com" Or LCase(addr) = "relevantemail2#outlook.com" Then
If InStr(1, Item.Body, LCase("next update due"), vbTextCompare) > 0 Then
Call errhandler
Else
'ask if we've added the date
prompt$ = "You're sending this to company x and have not added a 'next update due' date, do you need to add one?"
If MsgBox(prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check Address") = vbYes Then
Cancel = True
End If
Exit For
End If
End If
End If
Next
End Sub
I am still really getting to grips with the basics of outlook VBA and string functions etc therein. so my question is: can I find the string after the text "next update due:" (ideally I want a formatted date but a string will do for the time being)? Essentially there will always be two delimiters ": " to begin the date and a carriage return to end it. Once I can retrieve it I am able to export the relevant information to an excel document which I will however I am struggling with the initial retrieval of the string/date.
Hopefully you guys can help, more than happy to expand on the above code if needed.
relative simple regex might be used to extract particular date pattern from body
"next update due:(*):"
and your result will be captured in those parenthessis
or with specific date formatting:
"next update due:*(\d\d\/\d\d\/\d\d)*:"
if your date is like 10/01/15
I have made a few changes to your code and hopefully it will get you in the right track.
A few observations to help you with the code.
Always break long code into smaller functions to help you
Always declare variables
Always write comments to help you.
Here is the code I hope it helps
Public Sub application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim strAddress As String
Dim oRecipient As Recipient
Dim strNextDueDate As String
For Each oRecipient In Item.Recipients
If oRecipient.Type = olTo Then
' Get the address
strAddress = GetAddress(oRecipient)
' Check the adress for de
If HasToBeChecked(strAddress) Then
If InStr(1, Item.Body, LCase("next update due"), vbTextCompare) > 0 Then
'Get the value for the date.
strNextDueDate = GetStringBetweenStrings(Item.Body, "next update due:", vbCr)
' ------------------------------------------
' The rest of your code here.....
' ------------------------------------------
'Call errhandler
Else
'ask if we've added the date
prompt$ = "You're sending this to company x and have not added a 'next update due' date, do you need to add one?"
If MsgBox(prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check Address") = vbYes Then
Cancel = True
End If
Exit For
End If
End If
End If
Next
End Sub
' Fucntion to check if the address should be chnaged.
' We have it as a separate function so we can add more
' emails if needed.
Function HasToBeChecked(ByVal strAddress As String)
Dim arrAddresses As Variant
Dim i As Long
Dim ret As Boolean
' Load the array of addresses
arrAddresses = Array("relevantemail1#outlook.com", "relevantemail2#outlook.com")
For i = LBound(arrAddresses) To UBound(arrAddresses)
If LCase$(strAddress) = LCase$(arrAddresses(i)) Then
ret = True
Exit For
End If
Next i
'Return the value
HasToBeChecked = ret
End Function
' Function to retrive the address from a recipient object
Function GetAddress(ByRef oRecipient As Recipient) As String
Const strSCHEMA_PROPERTY_TYPE As String = "http://schemas.microsoft.com/mapi/proptag/0x3002001F"
Dim strAddresType As String
Dim ret As String
' Get the address accoring to if it's an excahnge or a regular email
strAddresType = oRecipient.PropertyAccessor.GetProperty(strSCHEMA_PROPERTY_TYPE)
If addrType = "EX" Then
ret = oRecipient.AddressEntry.GetExchangeUser.PrimarySmtpAddress
Else
ret = oRecipient.Address
End If
' Return the value
GetAddress = ret
End Function
' Function to get he string between teo strings
Function GetStringBetweenStrings(ByVal strToCheck As String, _
ByVal strStart As String, _
ByVal strEnd As String) As String
Dim lPosStart As Long
Dim lPostEnd As Long
Dim ret As String
lPosStart = InStr(1, strToCheck, strStart)
If Not lPosStart = 0 Then
lPosStart = lPosStart + Len(strStart) + 1
lPostEnd = InStr(lPosStart, strToCheck, strEnd)
If Not lPostEnd = 0 Then
ret = Mid$(strToCheck, lPosStart, lPostEnd - lPosStart)
End If
End If
' Return the value
GetStringBetweenStrings = ret
End Function
Thanks

How to show all validation errors as a list in my messagebox

I am having a problem with my code. I am trying to show all the validation errors in a message box. Can anyone tell me why only one of my errors is showing up in the box? I tried a couple more solutions and looked around but I need a little help please.
Public Class Form1
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
If Data_Validated_ok() = False Then Exit Sub
End Sub
Private Function Data_Validated_ok() As Boolean
Dim intErrCount As Integer
Dim strErrMessage As String = String.Empty
Dim ctrlError As New Collection
' make sure Premium channel is selected
If Me.lstPremium.SelectedIndex < 0 Then
intErrCount = intErrCount + 1
strErrMessage = intErrCount & ". Premium Channels is a required field." _
& vbCrLf
ctrlError.Add(lstPremium.SelectedIndex)
End If
' make sure a customer type is selected in the Radioboxes
If radBusiness.Checked = False And
radResidential.Checked = False Then
intErrCount = intErrCount + 1
strErrMessage = intErrCount & ".Customer Type is a required field." _
& vbCrLf
ctrlError.Add(radBusiness.Checked, radResidential.Checked)
End If
' make sure a business customer checks at least one option in the listbox
If radBusiness.Checked = True And Me.lstConnections.SelectedIndex < 0 Then
intErrCount = intErrCount + 1
strErrMessage = intErrCount & ". Business Customers must select 1 or more Connection." _
& vbCrLf
ctrlError.Add(lstConnections.SelectedIndex)
End If
' show all errors in a messagebox
If intErrCount > 0 Then
MessageBox.Show(strErrMessage, "Validation Rule(s)", MessageBoxButtons.OK, MessageBoxIcon.Information)
Dim ctrl As Control
ctrl = ctrlError.Item(1)
ctrl.Focus()
Return False
Else
Return True
End If
End Function
How about storing each error in a List(Of String)? Your variable ctrlError is not storing controls, but integers and booleans - you should have casting errors there.
Private Function Data_Validated_ok() As Boolean
Dim errorMsgs As New List(Of String)
' make sure Premium channel is selected
If Me.lstPremium.SelectedIndex < 0 Then
errorMsgs.Add("Premium Channels is a required field.")
End If
' make sure a customer type is selected in the Radioboxes
If radBusiness.Checked = False AndAlso
radResidential.Checked = False Then
errorMsgs.Add("Customer Type is a required field.")
End If
' make sure a business customer checks at least one option in the listbox
If radBusiness.Checked = True And Me.lstConnections.SelectedIndex < 0 Then
errorMsgs.Add("Business Customers must select 1 or more Connection.")
End If
' show all errors in a messagebox
If errorMsgs.Count > 0 Then
MessageBox.Show(String.Join(Environment.Newline, errorMsgs.ToArray), "Validation Rule(s)", MessageBoxButtons.OK, MessageBoxIcon.Information)
Return False
Else
Return True
End If
End Function

Getting mailaddresses out of recipients of an mailItem

I been trying to find out a way to find out which mail addresses a mail has been sent to. Consider the following:
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
Dim mai As MailItem
Dim intInitial As Integer
Dim intFinal As Integer
Dim strEntryId As String
Dim intLength As Integer
intInitial = 1
intLength = Len(EntryIDCollection)
intFinal = InStr(intInitial, EntryIDCollection, ",")
Do While intFinal <> 0
strEntryId = Strings.Mid(EntryIDCollection, intInitial, (intFinal - intInitial))
Set mai = Application.Session.GetItemFromID(strEntryId)
intInitial = intFinal + 1
intFinal = InStr(intInitial, EntryIDCollection, ",")
Loop
strEntryId = Strings.Mid(EntryIDCollection, intInitial, (intLength - intInitial) + 1)
MsgBox strEntryId
Set mai = Application.Session.GetItemFromID(strEntryId)
For Each Recipient In mai.Recipients
MsgBox Recipient
Next
End sub
In those msgBoxes I get the "nice name", Like "John Doe" - but I want to get the mail address, "john.doe#gmail.com".
How can I achieve this?
I assume this is Outlook 2007+. Have you tried the Address Property?
For Each Recipient In mai.Recipients
MsgBox Recipient.Address
Next Recipient
This should print the email address of each recipient.