Update SQL database through excel VBA - sql

First off I understand the process of having a user update a db via excel runs alot of risks, I appreciate any advise against this method but lets speculate that I have the perfect user who never makes mistakes :)
So firstly I've managed to access a stored procedure via vba in excel to pull data based on a parameter in a particular cell. Now if I wanted to update these fields how would I go about doing this?
My first suggestion would be to create a stored procedure that updates based on all the fields in spreadsheet. If this is the right avenue to follow how would I loop through all the rows?
Any other suggestions people could offer would be greatly appreciated.

Some notes on updating SQL Server. This [ODBC;FileDSN=z:\docs\test.dsn] can be any valid connection string.
Dim cn As Object, rs As Object
Dim scn As String, sSQL As String, sFile As String
sFile = ActiveWorkbook.FullName
scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & sFile _
& ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
''Late binding, so no reference is needed
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open scn
sSQL = "SELECT * INTO [ODBC;FileDSN=z:\docs\test.dsn].FromXL " _
& "FROM [Sheet8$]"
cn.Execute sSQL, recs
Debug.Print recs
sSQL = "INSERT INTO [ODBC;FileDSN=z:\docs\test.dsn].FromXL " _
& "SELECT * FROM [Sheet8$]"
cn.Execute sSQL, recs
Debug.Print recs
sSQL = "UPDATE [ODBC;FileDSN=z:\docs\test.dsn].FromXL x " _
& "INNER JOIN [Sheet8$] w " _
& "ON x.ID = w.ID SET x.Field =w.field"
cn.Execute sSQL, recs
Debug.Print recs
rs.Open "SELECT * FROM [ODBC;FileDSN=z:\docs\test.dsn].FromXL", cn
Debug.Print rs.GetString

You have to familiarize yourself with Microsofts COM Object. My VBA is rusty so watch out.
str t = Range("A1:A4").Value
If you are doing a lot of dynamic processing you should make yourself a wrapper method to some of the microsoft stubs.
function getValue(str location)
return Range(location + ":" + location).Value
end function
I've done large VBA projects before and reading values from the front end is a costly operation. You should set up objects to hold these values so you never have to read the same value more than once.
Lastly, you need lots and lots of validation, from everything between checking the database to make sure the user has the latest version to making sure that the spreadsheet isn't in print view (because this affects the range being able to read).
Verifying the version is important because you are going to need to release fixes and you need to verify that those fixes are being used.

Related

Writing SQL in VBA to obtain the record source which is equal to current ford

this is my first time posting, so I am hoping I give all the details I need to.
I am trying to get select a record sorce which is equal to the record which is currently displayed on the form to import data into Word using the bookmark function. I've got the word part to work, what I can't seem to fathom is the SQL in VBA. I spent a good couple of hours researching this and I know the SQL taken directly wont work, but I can't seem to work out what it needs to be changed to and after looking through other posts and implementing the changes others had suggested in other circumstances.
My SQL is:
SELECT TblJob.JobID, TblJob.JobTitle, TblJob.Location, TblJob.ScreeningQ1, TblJob.ScreeningQ2, TblJob.ScreeningQ3, TblJob.ScreeningQ4, TblJob.ScreeningQ5, TblJob.ScreeningQ6, TblJob.ScreeningQ7, TblJob.ScreeningQ8, TblJob.ScreeningQ9, TblJob.ScreenignQ10
FROM TblJob
WHERE (((TblJob.JobID)=[Forms]![FrmJob]![JobID]));
The code I was trying to implement was:
Dim rs As DAO.Recordset, strsql, val As String
val = Forms!FrmJob!JobID
strsql = "SELECT * FROM TblJob WHERE JobID = '" & val & "'"
Any help any one can offer would get greatly appreciated, I am still very much a beginner when it comes to coding and the posts on this site has been fantastic on helping me so far!
I figured this our, if the answer can help anyone else
strsql = "SELECT * FROM TblJob WHERE JobID=" & Me.JobID
You're very close. Here is a code of my script using ADODB library in Excel.
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
cn.Open "DRIVER={Oracle in OraClient11g_home1};" & "DBQ=" & Database_Name & ";UID=" &
User_ID & ";PWD=" & Password & ";"
strsql = "some_sql"
rs.Open SQLStr, cn
'Sheets(dane_wymag).Cells(knc + 1, 1).CopyFromRecordset rs

Insert Query/Select Query works in access, but not in vba

I have created a query that works great with no errors in Access, and while trying to translate this to my vba setup I can't figure out why I am not getting any values, even though the query clearly works in access, and causes no errors on the VBA side.
Pulling my hair out here, I have created a side table to see if I could "pseudo-insert" the calculated value, but I get the same issue as above - insert works with no errors in access, goes through in vba with no issues, but doesn't actually insert any data.
I have copied the string queries while pausing code to make sure EVERYTHING matches up between the Access query that works and the VBA query, and haven't found any differences.
I read somewhere since I am trying to pull a "first line" data piece that there may be some HDR setting that I could change, but when I tried to apply any fixes I found they opened another instance of excel and opened a dialogue box.
Please let me know what I am doing wrong here.
Public Function PullNextLineItemNumB(QuoteNum) As Integer
Dim strQuery As String
Dim ConnDB As New ADODB.Connection
Dim myRecordset As ADODB.Recordset
Dim QuoteModifiedNum As String
ConnDB.Open ConnectionString:="Provider = Microsoft.ACE.OLEDB.12.0; data
source=" & ThisWorkbook.Path & "\OEE Info.accdb"
'Query to try and make Access dump the value "18" into the table so I can
grab it after the query is finished, sidestepping excel not working
strQuery = "INSERT INTO TempTableColm (TempColm) SELECT
MAX(MID([Quote_Number_Line],InStr(1,[Quote_Number_Line]," & Chr(34) & "-"
& Chr(34) & ")+1)) AS MaxNum from UnifiedQuoteLog where Quote_Number_Line
like '" & QuoteNum & "*'"
ConnDB.Execute strQuery
'Original query, returns "18" as expected in Access, and null or empty in
the recordset
strQuery = "SELECT MAX(MID([Quote_Number_Line],InStr(1,
[Quote_Number_Line]," & Chr(34) & "-" & Chr(34) & ")+1)) from
UnifiedQuoteLog where Quote_Number_Line like '" & QuoteNum & "*'"
Set myRecordset = ConnDB.Execute(strQuery)
Do Until myRecordset.EOF
For Each fld In myRecordset.Fields
Debug.Print fld.Name & "=" & fld.Value
Next fld
myRecordset.MoveNext
Loop
myRecordset.Close
Set myRecordset = Nothing
ConnDB.Close
Set ConnDB = Nothing
End Function
Actual output from access is "18" which is expected, output from excel's vba recordset is always null or empty string.
It appears I solved the problem, while looking into this apparently the excel operator using ADODB with access is % for LIKE and NOT * (because reasons). As soon as I made that change everything started working.
Can someone explain why that is a thing? I really want to understand why this was a design choice.

Connecting to Access 2016 from Excel 2016 with VBA

I'm very new to VBA, and I've been trying to write some code in Excel 2016 that will, when a button is pressed, take a range of cells and write them to a table that I've set up in an Access 2016 database. I'm working out of an .xlsm workbook right now.
I've been basing my code off of the bulk-insert method (building an SQL "INSERT INTO" statement) that the submitter posted as an edit to this previous StackOverflow question Using Excel VBA to export data to MS Access table .
So far, here is the VBA I have written (or at least the part of it dealing with the importing into Access). When I run it, I get the error "Run-time error '-2147467259 (80004005)': Could not find installable ISAM.". I think the issue is in my connection string, which I've been having trouble with since I can't find any examples of properly-formatted connection strings on the Internet that use Access 2016 and Excel 2016 (mostly older versions).
' Set up the transfer into Access
Dim dbPath As String, dbWb As String, dbWs As String, scn As String, dsh As String, ssql As String
Set cn = CreateObject("ADODB.Connection")
dbPath = Application.ActiveWorkbook.Path & "\MyDatabase.accdb"
dbWb = Application.ActiveWorkbook.FullName
dbWs = Application.ActiveSheet.Name
scn = "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=" & dbPath
dsh = "[" & Application.ActiveSheet.Name & "$]" & "Data2" 'Data2 is the named range of data to be written to Access
' Open the connection with Access
cn.Open scn
' Create an SQL "Insert" statement using the name dsh developed earlier
ssql = "INSERT INTO DataPortfolio ([Field1], [Field2], [Field3]) "
ssql = ssql & "SELECT * FROM [Excel 16.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh
' Execute the SQL statement
cn.Execute ssql
Can anyone see where I may be going wrong? I assume it's in the connection string (scn), but I'm not sure.
Any help is appreciated! Many thanks.

Multiple Users Updating Excel Sheet - Maybe Disconnected ADO Recordset?

I have the below excel sheet that is set as shared and is being access by multiple users within the team:
Sheet http://im47.gulfup.com/xQTWqT.png
As the sheet is being updated with new records very often, I have set the below sharing options and that the sheet is being saved and the other users changes are being updated every five minutes (the minimum that you can set):
Options http://im47.gulfup.com/SBX4jf.png
The problem happens when 2 users try to update the database at the same time within the 5 minutes, then excel will prompt them that this cell already contains data and will offer to resolve the changes.
Is there any way to avoid this happening.
I have searched and come across Disconnected ADO Recordset, but I am not very clear on how they could aid in my scenario.
Any help will be highly appreciated.
Never mind I figured it out:
Create a user entry form in one workbook, and create another workbook for the storage of the data (lets call it Book1).
Next this is the code:
Private Sub CommandButton1_Click()
' Add the ActiveX Object Library
' Tools ---> References ---> Microsoft ActiveX Data Objects 2.5 Library
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
With cn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source=C:\Users\Name\Downloads\Book1.xls;" & _
"Extended Properties=Excel 8.0;"
.Open
End With
strSQL = "INSERT INTO [Sheet1$](Name, Age, Nationality, Amount) values('" & UserForm1.TextBox1.Value & "','" & UserForm1.TextBox2.Value & "','" & UserForm1.TextBox3.Value & "','" & UserForm1.TextBox4.Value & "')"
cn.Execute strSQL
End Sub

ado in excel, inserting records into access database

First time asker, usually I can find the answer by searching, but my google-fu seems weak today.
I have an excel workbook connecting to an access 2003 database to insert usage records
The code i'm using is:
sdbpath = ThisWorkbook.Path & "\Data.mdb"
sCommand = "INSERT INTO Usage VALUES('" & Environ("Username") & "',#" & Now() & "#)"
Dim dbCon As New ADODB.Connection
Dim dbCommand As New ADODB.Command
dbCon.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sdbpath & "; Jet OLEDB:Database Password=TestPass;"
dbCommand.ActiveConnection = dbCon
dbCommand.CommandText = sCommand
dbCommand.Execute
dbCon.Close
The code fails on the line dbCommand.Execute with run-time error '-2147217900 (80040e14)' : Automation error.
The database its trying to insert the record into contains one table, usage, with two columns - UserID and AccessDate, formatted as text and DateTime respectively.
The odd part is the connection string seems OK, since it fails after the connection is already open, yet if I take the sCommand value before the execute is run, then paste it into a query in access and execute that - it runs fine!
In case it was access struggling with the datetime format i've tried switching it to text (and the hashtags in the code) but that still fails. I've also tried specifying the column names too.
Can anyone shed some light on what i'm doing wrong? I've never had so much trouble with a very simple bit of SQL.
Thanks in advance!
In Access we need to specify the field-names. Even so, I found that I needed to wrap the table-name in square brackets before it would insert:
sCommand = "INSERT INTO [Usage] (UName, SomeDate) VALUES ('" & Environ("Username") _
& "',#" & Now() & "#)"