Check if sender is in SQL ODBC database - sql

I am using outlook 2010.
When I get an e-mail I need the following to happen:
Check the e-mail address of the sender against my ODBC database:
a. If found then save as .htm in a specific folder and write "1" on the the table's database.
b. If found two times then forward the e-mail to admin#mydomain.org with the subject: "Duplicate to sort manually"
c. If not found then forward it to admin#mydomain.org with the subject: "e-mail to be added to database"
Here is where I am now:
Public Sub ShowMessage(Item As Outlook.MailItem)
'connect to database
On Error Resume Next
Dim cnn As ADODB.Connection
Dim rst As New ADODB.Recordset
Dim cmd As ADODB.Command
Dim sSQL As String
Dim strConn As String
Set cnn = New ADODB.Connection
strConn = "DSN=mydsn;DATABASE=mydb;Trusted_Connection=yes;"
cnn.Open strConn
' Set cmd = New ADODB.Command
' cmd.ActiveConnection = cnn
sSQL = "SELECT id FROM dbo.mailing_list WHERE email_add = '" & Item.SenderEmailAddress & "'"
' cmd.CommandText = sSQL
rst.Open sSQL, cnn, adOpenStatic
email_add = rst!email_add
If rst.BOF And rst.EOF Then
' nothing found
Stop
ElseIf rst.RecordCount > 1 Then
' more than one record
Stop
Else
' one record
'
Dim Path As String
Path = "C:\"
End If
Dim strFromEmail As String
'name and format I want the email to be saved
Item.SaveAs Path, olMHTML
'if email is saved send an alert msg and if not send another one
If Item.Saved = True Then
Item.Delete
Else
MsgBox ("This email was not saved.")
End If
ex:
Set cnn = Nothing
Set cmd = Nothing
Set rst = Nothing
Set rst1 = Nothing
End Sub

Consider implementing the following scenarios:
Create a rule to run a macro which can do #a and #b.
The VBA sub should look like the following one:
Public Sub HandleNewMail(mail As MailItem)
' do something
End Sub
The Outlook object model provides the Forward method for items. It executes the Forward action for an item and returns the resulting copy as a MailItem object. The SaveAs method saves the Microsoft Outlook item to the specified path and in the format of the specified file type. If the file type is not specified, the MSG format (.msg) is used. Pass the olHTML value for the second parameter.
Handle the NewMailEx event of the Application class. It is fired when a new item is received in the Inbox.
It is up to you which way is to choose. But I'd suggest starting from the Getting Started with VBA in Outlook 2010 article in MSDN.

for the SQL-part I would use a separate module; i think the following should work. Use something like
Sub whatsoever()
Dim countsql As Integer
countsql = countemailadress("rechnung.wien#bechtle.com")
Debug.Print "COUNT = " & countsql
End Sub
to call it, then you have the answer in the "countsql" and can use this e.g. in a "case".
here the function:
Function countemailadress(searchforemail As String)
Dim mysql As String
Dim con As ADODB.connection
Dim rec As ADODB.recordset
Set con = New ADODB.connection
con.Open "DSN=mydsn;DATABASE=mydb;Trusted_Connection=yes;"
mysql = "SELECT Count(mailing_list.[email_add]) AS countemail_add FROM mailing_list where (mailing_list.[email_add]=" & searchforemail & ");"
Set rec = con.Execute(mysql)
rec.movefirst
countemailadress = rec.Fields(0)
End Function
I hope this helps,
Max

Related

How do I make a db connection to Excel that more than one user can open at same time?

You've help me to get to this point and now I'm stuck again. The macro works fine, but only one person can run it at any given time. If two users try to run it at the same time, they get a Runtime error. When I click Debug, it takes me to "myConn.Open"
To clarify, I'm not trying to allow multiple users to edit the Excel spreadsheet. They are only opening it read-only to get values from it, not to add or edit it in any way.
Public Sub Letter()
Dim rngStory As Word.Range
Dim rngCount As Long
Dim mySQLquery As String
Dim myKey As String
Dim mySource As String
Dim slkAddresseeName, slkRegarding, slkFileNum, slkSalutation As String
Dim slkTemplate As String
Dim myConn As ADODB.Connection
Dim myRs As ADODB.Recordset
Dim slkTempDoc As String
' Prompt user for Login ID
myKey = InputBox("Enter Attorney or Paralegal LOGIN ID (e.g., jtorres or b324):")
' Make DB connection
mySQLquery = "SELECT * FROM [All_Users$] WHERE LoginID = '" & myKey & "'"
mySource = "\\servername\vol1\macros\master\LetterMemoDB.xlsx"
Set myConn = New ADODB.Connection
Set myRs = New ADODB.Recordset
With myConn
.Provider = "Microsoft.ACE.OLEDB.12.0;Data Source=" & mySource & ";Extended Properties=""Excel 8.0;HDR=YES"";"
End With
myConn.Open
myRs.Open mySQLquery, myConn, adOpenStatic, adLockReadOnly
' End of DB connections
My guess is I'm using ACE as the provider and maybe it can't support multiple, simultaneous connections. What's the fix?
Fix was to change the Excel file to read-only via right click | Properties. Sorry for the stupid question.

How to return multiple values from table based on specific item that I entered?

I tried to use Tooling_No_AfterUpdate() for both Sub and Function but it prompt me 'Ambiguous name detected' as I know that I can't use the same identifier. Then, I changed the identifier and set it to public function but it doesn't work and prompt me 'User-defined type not defined'.
I'm creating a form for user to enter the tooling number to know the storage location where it can be more than one location. I tried to use ADODB.Recordset to get data from my asset table. So here's what I tried:
Private Function Tooling_No_Enter() As ADODB.Recordset
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
Set Tooling_No_Enter = CurrentProject.Connection.Execute("select FirstName, LastName from Employees")
End Function
Private Sub Tooling_No_AfterUpdate()
Dim strStorage_Location_1 As String
Dim strStorage_Location_2 As String
Dim strStorage_Location_3 As String
Dim strStorage_Location_4 As String
Dim strStorage_Location_5 As String
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
Set rst = Tooling_No_Enter()
Do While Not rst.EOF
strStorage_Location_1 = rst!Storage_Loacation_1
strStorage_Location_2 = rst!Storage_Loacation_2
strStorage_Location_3 = rst!Storage_Loacation_3
strStorage_Location_4 = rst!Storage_Loacation_4
strStorage_Location_5 = rst!Storage_Loacation_5
Debug.Print strStorage_Location_1 + vbCrLf + strStorage_Location_2 + vbCrLf + strStorage_Location_3 + vbCrLf + strStorage_Location_4 + vbCrLf + strStorage_Location_5
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
End Sub
After that, users able to choose the location while the chosen location will be recorded into asset table and transaction table and these are the parts i can't figure it out.
You are using the wrong method to open ADODB recordset. For one thing, Execute is used for action SQL (DELETE, UPDATE, INSERT).
One way to use a recordset object in multiple procedures is to declare recordset variable in module header. Example shows declaring and setting and opening connection and recordset objects which are then referred to in another procedure not shown.
Option Compare Database
Option Explicit
Public strOldLabNum
Dim cn As ADODB.Connection
Dim rsOldSample As ADODB.Recordset
___________________________________________________
Private Sub cbxOldLabNum_AfterUpdate()
Set cn = CurrentProject.Connection
Set rsOldSample = New ADODB.Recordset
strOldLabNum = Me.tbxOldYear & "A-" & Me.cbxOldLabNum
'select old sample info from table zSample
rsOldSample.Open "SELECT * FROM zSample WHERE LabNum='" & strOldLabNum & "';", _
cn, adOpenStatic, adLockPessimistic
End Sub

Excel VBA ADO SQL connection error - Could not find the object

I got a brilliant answer to my previous question from #Ryan Wildry but I thought I'd ask a different question regarding the same code: here goes.
Background Info
I have a shared (network/server) Excel template file which is both the input file and the data source (although on different sheets). Let's call that Input.xltm.
The code basically picks up a input in a range on Input Sheet, takes the first two letters and finds the closest code from Code Sheet, then populates a UserForm ListBox with the top five results.
The problem
The problem comes when users set off the UserForm and the error usually returns:
Run-time error '-2147467259'
The Microsoft Access database engine could not find the object 'C:\Users\user.name\Documents\Input1'. Make sure the object exists and that you spell its name and the path name correctly.......etc
I think it may have something to do with the fact Excel puts a number after the filename because it's a template file although I don't actually know!
The code
And here's the code:
Public MyConnection As New ADODB.Connection
Public MyRecordset As New ADODB.Recordset
Private Sub UserForm_Initialize()
Dim ColumnName As String: ColumnName = "[Variant code]"
Dim SearchStr As String: SearchStr = Left(Sheets("Input Sheet").Range("B4").Value2, 2)
Dim dbstring As String
dbstring = ThisWorkbook.FullName
Application.ScreenUpdating = False
If MyConnection.State <> adStateOpen Then
With MyConnection
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbstring & _
";Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1';"
.Open
End With
End If
If MyRecordset.State = adStateOpen Then MyRecordset.Close
MyRecordset.Open "Select top 5 " & ColumnName & " from [Code Sheet$] where " & ColumnName & _
" like '%" & SearchStr & "%'", MyConnection, adOpenForwardOnly, adLockReadOnly
Me.ListBox1.Clear
If Not MyRecordset.EOF Then MyRecordset.MoveFirst
Application.ScreenUpdating = True
Do Until MyRecordset.EOF
Me.ListBox1.AddItem MyRecordset.Fields(0).Value
MyRecordset.MoveNext
Loop
End Sub
I just need everyone who accesses the file through the server to be able to pick up the correct data source (which is only in the next sheet) and populate the ListBox.
I'd be thankful for any suggestions! Thanks
#UPDATE
I have checked, now if you open (and then save) the actual template file so there's no '1' after the file name, then the code works as expected. It's only when the template is opened normally and the number automatically appended that it stops working.
It seems that you do not make early-binding for MyConnection and MyRecordset first.
You can make a late-binding by
step 1.
Change
Public MyConnection As New ADODB.Connection
Public MyRecordset As New ADODB.Recordset
to
Public MyConnection As object
Public MyRecordset As object
.
step 2.
Add
Set MyConnection = createobject("adodb.connection")
Set MyRecordset = createobject("adodb.recordset")
before If MyConnection.State <> adStateOpen Then

query sql database for specific value in vb.net

I am trying to convert VBA code to vb.net, im having trouble trying to search the database for a specific value around an if statement. any suggestions would be greatly appriciated.
thedatabase is called confirmation, type is the column and email is the value im looking for. could datasets work?
Function SendEmails() As Boolean
Dim objOutlook As Outlook.Application
Dim objOutlookMsg As Outlook.MailItem
Dim objOutlookRecip As Outlook.Recipient
Dim objOutlookAttach As Outlook.Attachment
Dim intResponse As Integer
Dim confirmation As New ADODB.Recordset
Dim details As New ADODB.Recordset
On Error GoTo Err_Execute
Dim MyConnObj As New ADODB.Connection
Dim cn As New ADODB.Connection()
MyConnObj.Open( _
"Provider = sqloledb;" & _
"Server=myserver;" & _
"Database=Email_Text;" & _
"User Id=bla;" & _
"Password=bla;")
confirmation.Open("Confirmation_list", MyConnObj)
details.Open("MessagesToSend", MyConnObj)
If details.EOF = False Then
confirmation.MoveFirst()
Do While Not confirmation.EOF
If confirmation![Type] = "Email" Then
' Create the Outlook session.
objOutlook = CreateObject("Outlook.Application")
' Create the message.
End IF
If you want really convert your code to NET then I think you should remove the ADODB objects and use the System.Data.SqlClient classes. Of course some things are more difficult now because the ADO.NET really use a detached model to work with databases.
The semi-equivalent of your code using the ADO.NET classes
....
' Use Try/Catch not the On Error Goto....'
Try
Dim conStr = "Server=myserver;Database=Email_Text;User Id=XXXX;Password=XXXXX;"
Using MyConnObj = new SqlConnection(conStr)
' Getting all the details rows and columns, '
' but you should select only the columns needed here....'
Using cmdDetails = new SqlCommand("SELECT * FROM MessagesToSend", MyConnObj)
' You need only the rows with Type=Email, so no need to retrieve all the rows'
Using cmdConfirm = new SqlCommand("SELECT * FROM Confirmation_list " & _
"WHERE [Type] = 'EMail' ", MyConnObj)
MyConnObj.Open
Using da = new SqlDataAdapter(cmdConfirm)
Dim dt = new DataTable()
da.Fill(dt)
Using reader = cmdDetails.ExecuteReader()
While reader.Read()
For Each row in dt.Rows
... ' The Outlook app should be instanced outside the loop'
Next
Loop
End Using
End Using
End Using
End Using
End Using
Catch x As Exception
MessageBox.Show("Error:" & x.Message)
End Try
Possibly the usage of the Type column is causing an issue. You might be able to get this working by doing the following:
confirmation.Fields("Type").Value
instead of
confirmation![Type]
but I would recommend you look into ADO.NET isntead of using ADODB as this is quite old now.

Query regarding dsn string

Below is the code to fill a list box in a VBA application :
Private Sub Form_Open(Cancel As Integer)
''#Populate list box control.
Dim cnn As ADODB.Connection
Dim strSQL As String
Dim rst As ADODB.Recordset
Dim strList As String
On Error GoTo ErrHandler
''#Use DSN to Northwind.
''#Modify connection and connection string as needed.
Set cnn = New ADODB.Connection
cnn.Open "DSN=NorthwindExample"
strSQL = "SELECT * FROM Shippers"
Set rst = New ADODB.Recordset
rst.Open strSQL, cnn
strList = rst.GetString(adClipString, , ";", ",")
Debug.Print strList
Me.lstShippers.RowSource = strList
rst.Close
cnn.Close
Set rst = Nothing
Set cnn = Nothing
Exit Sub
ErrHandler:
MsgBox Err.No & ": " & Err.Description, vbOKOnly, "Error"
Set rst = Nothing
Set cnn = Nothing
End Sub
I need to know what i need to put as DSN string? Where will I get the info?
What is adClipString here in this code?
Is there any option to populate list control without using DSN connection object since I am taking the values from the same access table?
Here is a link that contains the different connection strings for Access:
http://www.connectionstrings.com/access
Something like this should work: Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;User Id=admin;Password=;
Im not sure what adClipString is, it could be an undeclared variable or database column?
Matt
Here is the info on adClipString.
Basically, GetString method gets the content of the entire recordset into a string variable where columns will be separated by ";" and rows will be separated by "," (as per your code).
Regarding DSN - see Start -> Settings -> Control Panel -> Administrative Tools -> Data Sources (ODBC). One of the tab (I guess System DSN) is where ODBC based data source can be created and are listed.