Excel from email inbox to SQL Server database - sql-server

I have to import data from Excel into a SQL Server database.
I am getting Excel files via email daily. I have to get them out from email and put the contents into the database. Also, I want to automate it instead of doing it manually.
I am thinking of below ideas:
Fetching the email attachment out of the inbox (automated process using some tool etc.) and save it to say the O: drive (then it's simple to pull into the database from there)
Taking help of any tool available (open source) and get the Excel content into SQL Server directly from the inbox.
I hope that makes sense about what I am trying to do.
Can someone please tell me how to automate this?
Thanks,
AP

You can use VBA for everything here.
1) Download attachments from Outlook.
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
sSaveFolder = "C:\Users\DT168\Documents\outlook-attachments\"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
End Sub
2) Load data from Excel file(s) into SQL Server.
Sub InsertARecord()
Dim cnt As ADODB.Connection
Dim rst As ADODB.Recordset
Dim stCon As String, stSQL As String
Set cnt = New ADODB.Connection
Set rst = New ADODB.Recordset
stCon = "Provider=MSDASQL.1;Persist Security Info=False;Data Source=JOEY"
cnt.ConnectionString = stCon
stSQL = "INSERT INTO MyTable (FieldNames)"
stSQL = stSQL & "VALUES (ActualValues)"
stSQL = stSQL & "WHERE lockStatus = 'nolock'"
cnt.Open
rst.Open stSQL, cnt, adOpenStatic, adLockReadOnly, adCmdText
If CBool(rst.State And adStateOpen) = True Then rst.Close
Set rst = Nothing
If CBool(cnt.State And adStateOpen) = True Then cnt.Close
Set cnt = Nothing
End Sub
Also, see this URL.
https://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm#Introduction

Related

Connect to SQL Server in VBA if the server requires specific username and password?

I realized today that when you connect to SQL Server data source in Excel's native connection, it doesn't allow you to enter in a specific username and password. It just asks for server name and database.
In VBA , under the assumption that I wanted to import data from a SQL Server data query into Sheet1, can you please help me understand how to write that code?
For purposes of this exercise:
SQL Server Connection INFO
Server Name: TestingS,1633
Database Name: CarSales
username: car
password: sales
The query I want to run for simplicity sake can be: "select * from table"
I have been doing some research , but am getting a bit lost. I have no problem setting up standard queries with custom SQL via ODBC, but because I need VBA, it's very tricky for me. Please help.
This is an example of MSSQL.
Sub testMSSQL()
'Reference Microsoft ActiveX data object Library 2.8 ~~
Dim cnn As ADODB.Connection
Dim strSQL As String
Dim Ws As Worksheet
Set Ws = ActiveSheet
strSQL = "select * from table"
Set cnn = New ADODB.Connection
'Set the provider property to the OLE DB Provider for ODBC.
'cnn.Provider = "MSDASQL"
'cnn.Provider = "Microsoft.ACE.OLEDB.12.0"
'cnn.Provider = "MSOLAP"
cnn.Provider = "SQLOLEDB.1" '<~~ mssql
' Open a connection using an ODBC DSN.
cnn.ConnectionString = "driver={SQL Server};" & _
"server=TestingS;uid=car;pwd=sales;database=CarSales"
Set rs = New ADODB.Recordset
rs.Open strSQL, cnn.ConnectionString, adOpenForwardOnly, adLockReadOnly, adCmdText
cnn.Open
If cnn.State = adStateOpen Then
Else
MsgBox "Not connected server"
Exit Sub
End If
If Not rs.EOF Then
With Ws
.Range("a1").CurrentRegion.ClearContents
For i = 0 To rs.Fields.Count - 1
.Cells(1, i + 1).Value = rs.Fields(i).Name
Next
.Range("a2").CopyFromRecordset rs
.Columns.AutoFit
End With
Else
MsgBox "No Data!!", vbCritical
End If
rs.Close
Set rs = Nothing
cnn.Close
Set cnn = Nothing
End Sub

How to pass username and password in external file into Excel Data Connection

I have numerous excel files which connect to our Oracle database.
However, the connection details are stored in plain text in the connection details.
These Excels are accessed by numerous different people.
I need to 'pass' the password and username from an external file into the connection in order to protect the database credentials.
The connections are only used by automated jobs on my machine. Therefore, other users don't need to use the connections.
My automated jobs use VBS scripts so a workaround in there would be best.
The portion of VBS which deals with this is
Dim xlApp, xlBook
Set xlApp = CreateObject("Excel.Application")
xlApp.DisplayAlerts = False
Set xlBook = xlApp.Workbooks.Open("where workbook is located", False)
xlApp.Run "SampleMacroName()"
xlbook.Save
xlBook.Close False
set xlBook = Nothing
xlApp.Quit
Set xlApp = Nothing
DisplayAlerts=false
Is there anyway to reference the password and username here?
Ideally we are looking for the simplest solution, so if we could hardcode them in this code that would be acceptable.
I had to delete my connections in the database and use VBA code to replicate my connections in a series of SQL queries. The basis of the code that I am using is:
'Declare variables'
Set objMyConn = New ADODB.Connection
Set objMyRecordset = New ADODB.Recordset
Dim strSQL As String
'Open Connection'
objMyConn.ConnectionString = "Driver={Microsoft ODBC for Oracle}; " & _
"CONNECTSTRING=(DESCRIPTION=" & _
"(ADDRESS=(PROTOCOL=***)" & _
"(HOST=*****)(PORT=****))" & _
"(CONNECT_DATA=(SERVICE_NAME = ****))); uid=****; pwd=*****;"
objMyConn.Open
'Set and Excecute SQL Command'
strSQL = "Select distinct * From Temp_Final_Complaints_Report"
'Open Recordset'
Set objMyRecordset.ActiveConnection = objMyConn
objMyRecordset.Open strSQL
'Copy Data to Excel'
Sheets("Complaints Report").Range("A2").CopyFromRecordset (objMyRecordset)
I can now encrypt the module where this is saved with a password.

ADODB Recordset not editable when using Access as backend, works fine with SQL Server

I've got a simple MS Access 2013 form with some text boxes, each of whose Control Source is set to fields in an ADODB recordset. The recordset may come from either a table in the current accdb project or as the result of a SQL Server stored procedure; this is set by selecting a radio button on the form.
I've confirmed that each of the two recordsets are updateable in vba code but when I use the form it will only allow me to edit fields returned from the SQL Server option; the Access option displays records but acts as if the text box is locked when I attempt to edit it.
This is the code I'm using:
Private Sub cmdLoadData_Click()
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
With rst
.CursorLocation = adUseClient
.CursorType = adOpenDynamic
.LockType = adLockOptimistic
End With
Select Case BackendOptions
Case 1
' Access
With rst
.ActiveConnection = CurrentProject.AccessConnection
.Open "SELECT Id, FirstName, LastName, Birthday FROM tblADOTest"
End With
Case 2
' SQL Server
Dim cn As New ADODB.Connection
With cn
.ConnectionString = "Driver={SQL Server Native Client 11.0};" & _
"Server=<the server name>;" & _
"Database=<the database name>;" & _
"Trusted_Connection=yes;"
.Open
End With
With rst
.ActiveConnection = cn
.Open "EXEC dbo.GetTestData"
End With
End Select
Set Me.Recordset = rst
End Sub
The stored procedure runs the same SQL as the inline string I'm using for Access.
Any ides on how to make the Access option editable?
helped me solve a similar problem using this:
.ActiveConnection = CurrentProject.Connection

Importing more than 1000 rows from Excel to SQL-server

The process is run in the environment of Excel VBA 2010 and MS SQL Server 2008.
Assume that there is a simple one column data with 1500 rows in an Excel-sheet and we want to export it to the database with SQL-queries in VBA code (SQL procedure in VBA exports maximum 1000 rows at once in default mode).
There is one limitation in this problem: the export procedure must be with dbclass-connection instead of ADODB connection. (The code-owner is not me. The code-owner is using dbclass for a quite big VBA code, so probably he wouldn't accept to change the whole code).
I found an option like lngRecsAff for ADODB.Connection which is used like:
Sub test()
Dim cn As ADODB.Connection
Dim strSQL As String
Dim lngRecsAff As Long
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\test.xls; Extended Properties=Excel 8.0"
strSQL = "Insert INTO [odbc;Driver={SQL Server};Server=SQL09;Database=Tom;UID=userID;PWD=password].tbl_test1 Select * FROM [Sheet1$]"
cn.Execute strSQL, lngRecsAff
cn.Close
Set cn = Nothing
End Sub
I tried to implement that lngRecsAff in my dbclass execution like:
Sub test()
Dim connOk As Boolean
Dim rs As New ADODB.Recordset
Set dbclass = New clsDB
Dim Value1() As Variant
Dim lngRecsAff As Long
Dim strSQL as String
Dim mstrErr as Boolean
dbclass.Database = "database_name"
dbclass.ConnectionType = SqlServer
dbclass.DataSource = "server_name"
dbclass.UserID = Application.UserName
connOk = dbclass.OpenConnection(False, True)
If connOk = False Then
MsgBox "Unsuccessful connection!"
Else
MsgBox "Successful connection"
End If
strSQL = "INSERT INTO [dbo].[table1](Column1) Values('" & Value1 & "')"
mstrErr = dbclass.ExecuteSQL(strSQL, lngRecsAff) ' The result mstrErr is a Boolean
' Some closing options here
End Sub
I got en error like lngRecsAff is not suitable for my ExecuteSQL procedure. Normally my execution mstrErr = dbclass.ExecuteSQL(strSQL) works without any problem.
Maybe I can do the SQL-procedure with a for-loop, then I can send the data in small pieces. But I want to find a more efficient, "nicer" solution which sends the whole array at once.
So is there any special option for dbclass which can send more than 1000 rows from Excel to the database?
You can query the Excel-Sheet directly using liked server.
In your Management Studio click to "Server Objects" and then right click onto "linked server". There you'll be able to add a new linked server.
If you need further help you can find tuorials easily. One is here:
https://www.mssqltips.com/sqlservertip/2018/using-a-sql-server-linked-server-to-query-excel-files/

Execute SQL Server stored procedure in VBA with multiple outputs

I have a stored procedure in SQL Server that I am trying to execute from Excel via some VBA code. However, the stored procedure has two outputs (see below).
My record set is only pulling in the first table (added 0 error messages...) whereas I want to pull in the second table.
Image here: http://i.stack.imgur.com/LxyLi.png
Here is my code, compiled from other sources I found on here:
Sub RefreshBarcodes()
Dim Database As String
Dim con As ADODB.Connection
Dim strconn As String
Dim SQLServer As String
Dim Session As String
Dim strSQLCommandOne As String
Application.ScreenUpdating = False
Worksheets("Master").Activate
Database = Worksheets("Master").Cells(5, "H").Value
SQLServer = Worksheets("Master").Cells(4, "H").Value
Session = Worksheets("Master").Cells(6, "H").Value
'Connect to Database
Set con = New ADODB.Connection
strconn = "Provider=sqloledb; Data Source=" & SQLServer & ";Initial Catalog = " & _
Database & "; INTEGRATED SECURITY=SSPI; "
con.Open strconn
'Set SQL Commands
strSQLCommandOne = "set nocount on; exec spGetSessionSourceCounts 'HNW-CLU-001-024_01_0005'"
'Open Recordset
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
'Execute and copy to Excel
rs.Open strSQLCommandOne, strconn
rs.MoveFirst
Worksheets("Session").Activate
Cells(1, 1).Select
ActiveCell.CopyFromRecordset rs
rs.Close
Worksheets("Master").Activate
Cells(6, "H").Value = "Session updated"
con.Close
Application.ScreenUpdating = True
End Sub
Excel output: http://i.stack.imgur.com/b7i3B.png
I would love to be able to pull in the first (error message) and second results (session info), but mainly need only the second table. Thanks so much in advance!
To access the second recordset, you need to execute this line:-
'Activate the next available recordset
Set rs = rs.NextRecordset
If Not rs Is Nothing Then
'Add code in here
End If

Resources