I'm developing a desktop application for my company (it's just a prototype, actually) for bringing simple services to production department (tool and process instructions, presence records, product traceability, etc).
I'm using VB.net and wpf; some MS Access databases are the backend. It uses Access Database Engine 2016.
I have a simple function used to update database records, here's it:
Public Function UpdateDatabaseRecord(DatabaseNumber As Integer, tblName As String, SearchInColumn As String, SearchBy As String, UpdateColumn As String, UpdateTo As String) As Integer
Try
Using ServerConnection As New OleDbConnection(ConnectionSelector(DatabaseNumber))
Dim CommandString As String
If SearchInColumn <> "ID" Then
CommandString = "UPDATE [" & tblName & "] SET [" & UpdateColumn & "]=#UpdateColumn WHERE [" & SearchInColumn & "] = " & DQ & SearchBy & DQ
Else
CommandString = "UPDATE [" & tblName & "] SET [" & UpdateColumn & "]=#UpdateColumn WHERE [" & SearchInColumn & "] = " & SearchBy
End If
Dim CommandUpdate As New OleDbCommand(CommandString, ServerConnection) With {.CommandTimeout = 10000}
With CommandUpdate.Parameters
.AddWithValue("#UpdateColumn", UpdateTo)
End With
ServerConnection.Open()
CommandUpdate.ExecuteNonQuery()
ServerConnection.Close()
End Using
UpdateDatabaseRecord = 0
SetCentralTimeStamp(DatabaseNumber, tblName)
Catch ex As Exception
Msg(Reflection.MethodBase.GetCurrentMethod.Name & NewLine & ex.Message & NewLine & "Err. Number " & Err.Number, "Database Error", MessageBoxButton.OK, MessageBoxImage.Error)
UpdateDatabaseRecord = Err.Number
End Try
End Function
Sometimes the application uses this function in the main thread; sometimes it runs it from scheduled task (clocked by a forms.timer every two minutes). This tasks aren't obviously in the main thread, but the code has been used succesfully for a couple of months with computers directly connected to company network via LAN cable. Recently I tried my application on a laptop connected via wifi to the company network, and I get an exception that's crashing my app. I installed VS on that laptop to debug the code, and I found that an AccessViolationException is raised on line "CommandUpdate.ExecuteNonQuery".
I tried to google it but it seems that this exception shouldn't be raised from managed code.
The error occours only with laptop connected via wifi.
Also, another function reads data from the databases: sometimes I get the same error in it, in the line where the connection is being opened (connection.open).
What should I check?
Thanks in advance.
ps "ConnectionSelector" is a simple function which returns the appropriate ConnectionString based on database number.
EDIT 1 - The WiFi network is created plugging directly a LAN cable from the actual wired network, using a common wireless router. IP addresses are automatically assigned and the connection works, since the app is able to get data from databases.
I solved the problem myself and I'm posting here the solution I found: I hope it will help someone in the future.
I resolved simply enabling all OLEDB Services for the database connection. It looks like connection pooling really help stability and performance, especially when using a wifi network like I'm forced to do. If you want, Google "OLEDB Services" and look for enabling them all.
Related
For reporting purposes, I'm importing data from various sources on the net into an Excel Workbook.
Problem is: while some of the stuff I want is on my company's private network (requiring cable connection), some of the URL/webservices I want to connect to are not allowed by my company's proxy (via cable connection).
Thus, I have to use another connection without proxy (via WiFi) to get those to work.
This WiFi connection is always active on my computer, but it requires me to manually unplug the cable for half of my imports and to plug it back to access files on my company's network for the other half...
I wonder if there is a way with VBA to tell the computer to use cable / WiFi according to what I need.
I am working on a Windows XP Pro computer with Excel 2010/VBA. Please help!
Found Two ways to enable or disable i.e change internet adapter connection from VBA:
'adjust these according to your need i.e change adapter name, change enabled or disabled parameter, change path, change file name etc. VBS approach is long but gives more control. Bat approach is short but limited IMO
1 Using vbs Source link :
'file name: asdf.vbs
'Get and disable all physical wired adapters (AdapterTypeID=0) (Ethernet 802.3)
'Wscript.Echo "test"
Set wmi = GetObject("winmgmts:root\CIMV2")
Set adapters = wmi.ExecQuery("Select * from Win32_NetworkAdapter where _
AdapterTypeId=0 AND NetConnectionID IS NOT NULL",,48)
For Each adapter in adapters
With adapter
WScript.Echo "available: " & .Availability & " enabled: " & .NetEnabled & " netconStatus: " & .NetConnectionStatus & " status: " & .Status & " netconnID: " & .NetConnectionID & " adType: " & .AdapterType
'adapter.disable()
'adapter.enable()
End With
Next
' Get and disable all physical wireless adapters (AdapterTypeID=9) (wireless)
2 Using bat Ref link1 and Ref link2 :
'file name: switch_lan6.bat
#echo off
start /MIN cmd.exe /c "netsh interface set interface name="Local Area Connection 6" admin=disabled"
Running these inside excel vba:
Shell "wscript ""C:\Users\USER\Desktop\asdf.vbs""", vbNormalFocus
or,
Call Shell(ThisWorkbook.Path & "\switch_lan6.bat", 0)
In an application that uses a MS Access form as a front-end to some SQL databases, I use DBEngine.CreateWorkspace to get a workspace, then workspace.OpenDatabase to connect to my remote SQL server via a defined ODBC System DSN. This all works quite nicely, until someone disconnects the remote SQL machine from the network, or shuts it down, or something else similarly ridiculous. (Note: I know there's a lot ridiculous about this setup, but unfortunately it's an inevitability at this point)
My question is:
Is there a way to elegantly deal with the timeout and subsequent 'SQL Server does not exist or access denied' error messages that come up, within the VBA code? workspace.OpenDatabase throws an error that I can catch and deal with, but not before two popups come up and stop my VBA code until an operator clicks OK.
DoCmd.SetWarnings False doesn't affect it as the error popups are not actually coming from Access itself - I think they're from the underlying ODBC process or the Jet Engine that drives it.
Any ideas?
A good solution can be found here:
ACC2000: How to Trap ODBC Logon Error Messages
http://support.microsoft.com/kb/210319
The above is from Access 2000 and is 14 years old, but as such it still works fine today. The other possible advantage is you don’t have to adopt and introduce ADO into your application. For applications that already use or have ADO, then no big deal, but if your application sticks to one data object model, then you not have to potentially introduce ADO.
The other BIG bonus of the above is this effectively logs you into the database and thus you avoid having user name and passwords in the linked tables. This means you can have different users and logons, and NOT have to re-link or embed the user name or password in your linked tables.
This wonderful trick and result of the above connection trick is outlined here:
Power Tip: Improve the security of database connections
http://blogs.office.com/b/microsoft-access/archive/2011/04/08/power-tip-improve-the-security-of-database-connections.aspx
I eventually found something that works by searching 'Suppress ODBC connection failure warnings'.
Courtesy of Trevor Best from http://bytes.com/topic/access/answers/201502-how-suppress-odbc-connection-dialog
Some code that uses ADO to make the database connection in a way that allows VBA error trapping to catch the error before the system throws any popups at you.
Function CanOpenSQLDbLB(pstrServer As String, pstrDb As String, pstrUser
As String, pstrPassword As String, Optional pfReportError As Boolean =
True) As Boolean
On Error GoTo CanOpenSQLDbLB_Err
Dim objConn As Object
Dim strConn As String
Dim strError As String, lngErr As Long
Const cstrSQLErr = "[Microsoft][ODBC SQL Server Driver][SQL Server]"
Set objConn = CreateObject("ADODB.Connection")
strConn = strConn & "DRIVER=SQL Server"
strConn = strConn & ";SERVER=" & pstrServer
strConn = strConn & ";APP=" & Application.Name
strConn = strConn & ";WSID=AWorkstation"
strConn = strConn & ";DATABASE=" & pstrDb
objConn.Open strConn, pstrUser, pstrPassword
CanOpenSQLDbLB = True
CanOpenSQLDbLB_Exit:
On Error Resume Next
objConn.Close
Set objConn = Nothing
Exit Function
CanOpenSQLDbLB_Err:
lngErr = Err.Number
strError = Err.Description
If InStr(1, strError, cstrSQLErr) Then
strError = "Error reported by server" & vbCr & vbCr &
Replace(strError, cstrSQLErr, "")
End If
Select Case lngErr
Case Else
If pfReportError Then
MsgBox strError, 16, "Error #" & Err & " Attempting to
open server database"
End If
End Select
Resume CanOpenSQLDbLB_Exit
End Function
For Example,
In my vb.net application i have created two forms called FormA and FormB.When completes the FormA 's load dbMonitor shows Connection is returned to pool. Pool has 4 connection(s) and in the case of Formb dbMonitor shows Connection is returned to pool. Pool has 5 connection(s).when i use two form at a time the total connections will be 9.
do i need to clear all connection after form's load, if yes which method is safe
sometimes facing max connection problems while using my application via network computers.
VB.NET code to open connection is below
i have created a module for the connection
Imports Devart.Data.PostgreSql
Module Myconnstrection
Public Myconnstr As New PgSqlConnection("Server=" & gstrServerName & ";Port=" & gstrPort & ";Database=" & gStrDBName & ";User ID=" & gstrUserName & ";Password=" & gPassword)
End Module
i use the MyConnstr in my forms load or where ever a connection to the database is needed
try
Dim adapter As PgSqlDataAdapter = New PgSqlDataAdapter(strSql,
MyConnstr) myconnstr.open()
'Do my job
catch
finally
myconnstr.close()
end try
Databsase : PostgreSQL 9.2
OS : windows
First time I'm using stackoverflow so here goes...
I've been getting errors intermittently when I try to run a macro in excel which I use for pulling in data from a CSV file. The error normally goes away if I start a fresh session, but this time it's been particularly persistant. It basically errors on the .Open line below, giving me a "Run-time error '2147467259' (80004005) Unspecified error":
Public Sub LoadFile()
file_path = Range("FlatFileLocation")
Set oConn = CreateObject("ADODB.Connection")
strcon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & file_path & "; Extended Properties=""text;HDR=Yes;FMT=Delimited(,)"";"
oConn.Open strcon
.....
Other info:
1) the file I'm trying to access is not open by another user
2) I close my connections at the end of the sub. also, i just tried restarting my machine and the error happened the first time I tried running the file
3) When I open my session up without any of my existing addins it seems to work. Is there any way of checking whether there is some sort of addin conflict going on?
There were other posts that suggest using CSVReader. Questions I have before trying this route are:
1) can I use this CSVReader across multiple user machines? The problem I would have here is needing to install it on a number of machines. I might be able to put a file on a shared drive however.
2) Can I query the resultant file with a SQL string? At the moment I use something like this:
....
strsql = "SELECT * FROM ( " & strsql & " ) WHERE ( ABS(PrevRisk) + ABS(CurrRisk) >= " & RiskThreshold & " ) ;"
Set oResult = New ADODB.Recordset
oResult.Open strsql, oConn
....
Thanks in advance for your help!
I am currently writing some software in visual studio to analyse large amounts of data from an Access database using SQL. I have code to make a new calculated variable but am struggling with the amount of time it takes to write the data back into Access.
I am currently using some vb com code to communicate with my Access Database which is running in 2002/3 comparability mode. The following is my current code which runs a function in a loop to write to the database.
cnnOLEDB = New OleDbConnection
cnnOLEDB.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & DataDirectoryName & DatabaseFileName
cnnOLEDB.Open()
'cmdOLEDB = New OleDbCommand
cmdOLEDB.Connection = cnnOLEDB
ColumnString = "ID_VAR, ID_PAR, TimeValue, strValue, ID_UPL"
For RecordCounter = 0 To CalcData.GetLength(1) - 1
Var_ID = Var_ID + 1
ValueString = Format(Var_ID, "0") & ", " & Format(Parameter, "0") & ", #" & Date2String(CDate(CalcData(0, RecordCounter))) & "#, " & CalcData(CalcData.GetLength(0) - 1, RecordCounter) & ", " & Format(AsUpload, "0")
If DatabaseConnectionInsert("INSERT INTO " & TableName & " (" & ColumnString & ") VALUES (" & ValueString & ")", "Non-Query") = "Error" Then GoTo Close
Next
cnnOLEDB.Close()
Here is the Function:
Public Function DatabaseConnectioninsert(ByVal Query As String, ByVal Task As String) As String
'On Error GoTo Err
'If cnnOLEDB.State = ConnectionState.Open Then cnnOLEDB.Close()
cmdOLEDB.CommandText = Query
Select Case Task
Case "Read Recordset"
rdrOLEDB = cmdOLEDB.ExecuteReader()
DatabaseConnectioninsert = "Read Recordset"
Case "Read Scalar"
DatabaseConnectioninsert = cmdOLEDB.ExecuteScalar
Case "Non-Query"
cmdOLEDB.ExecuteNonQuery()
DatabaseConnectioninsert = "Non-Query"
End Select
Exit Function
Err:
MsgBox("Database connection error.")
DatabaseConnectioninsert = "Error"
End Function
I am currently trying to insert ~4500 records into the Access Database for each Parameter which takes ~3minutes. However when the project goes live it will have to deal with over 100000 records per Parameter so it is no where near fast enough.
To solve this issue I am thinking of either updating my code to .net or creating a record set, so I can move all of the data in Access at once. Can anyone give me some advice as to which will have the greatest impact to improving the speed of the inserts. I am running visual studio 2005 and Access 2007, updating the database to 2007 rather than compatibility mode is possible but not ideal , however my current code can't access it.
Thank you for your help
Josh
As ridiculous as it sounds, the very best performance you will get on an Access database is using the ancient DAO COM library. Use a RecordSet object to add the records one at a time in a loop and reference the fields by their index (ordinal position) rather than their names. You will find it much, much quicker than using oleDB.ExecuteNonQuery.
See the solution given here for more information. It's C# but it's easy enough to follow and convert to VB.NET if you want to try it out.
Edit
In deference to Remou's comments below: it would appear that Microsoft have in fact been keeping DAO technology up to date – in spite of declaring it obsolete back in 2002 – but you have to use the Office Access Redistributable rather than the better known DAO 3.6 library.