There is an old VB application running at one of my clients.
An exception is throws in this peice of code:
cn=GetIndexDatabaseConnectionString()
sSql="SELECT * FROM Arh_Naroc WHERE StNarocila = '" & isci & "'"
rs=CreateObject("ADODB.Recordset")
Call rs.Open(sSql,cn)
The exception happens in rs.Open() function. "Error number 440 occured."
This are SBL scripts for KOFAX engine and it's many years old.
The whole SW was transferred from old XP computer to Windows 7 and looks like there are problems everywhere.
Can some one help me determine what is the problem here. At least if I could get a proper error message back in msgbox would be most helpful.
EDIT:
This is the connection string function.
Function GetIndexDatabaseConnectionString
Dim objXmlDocument As Object
Dim objXmlGlobalSettingsFileParh As Object
Dim objXmlIndexDatabaseConnectionString As Object
Dim strGlobalSettingsFilePath As String
Dim strTemp As String
Const strSettingsFilePath = "C:\Data\LocalDocsDistibutingSystem\Settings.xml"
Set objXmlDocument = CreateObject("MSXML2.DOMDocument")
objXmlDocument.Load strSettingsFilePath
Set objXmlGlobalSettingsFileParh = objXmlDocument.selectSingleNode("DocsDistributingSystem/GlobalSettingsFilePath")
strGlobalSettingsFilePath = objXmlGlobalSettingsFileParh.childNodes(0).Text
Set objXmlGlobalSettingsFileParh = Nothing
Set objXmlDocument = Nothing
Set objXmlDocument = CreateObject("MSXML2.DOMDocument")
objXmlDocument.Load strGlobalSettingsFilePath
Set objXmlIndexDatabaseConnectionString = objXmlDocument.selectSingleNode("DocsDistibutingSystem/AscentCapture/IndexDatabase/ConnectionString")
strTemp = objXmlIndexDatabaseConnectionString.childNodes(0).Text
Set objXmlIndexDatabaseConnectionString = Nothing
Set objXmlDocument = Nothing
GetIndexDatabaseConnectionString = strTemp
End Function
This is the relevant line from Settings.xml:
<ConnectionString> Provider=OraOLEDB.Oracle;Data Source=LINO2;User Id=****;Password=****;OLEDB.NET=True; </ConnectionString>
The real data is masked with *. The connection to Oracle appears to be ok. I created ODBC and linked server to sql using the provider and connection data. It works. It must be something missing installed on the computer for ADODB to work...
The connection appears to be working OK. There is no error when its initialized.
The error happens in Call rs.Open(sSql, cn). All i want is the detailed error message when the error happens...
Many thanks.
As it states on MS Knowledge Base
An error occurred while executing a method or getting or setting a
property of an object variable. The error was reported by the
application that created the object. Check the properties of the Err
object to determine the source and nature of the error. Also try using
the On Error Resume Next statement immediately before the accessing
statement, and then check for errors immediately following the
accessing statement.
So as they suggest check the Err object, in a similar fashion to:
If Err.Number <> 0 Then
Msg = "Error: " & Str(Err.Number) & ", generated by " _
& Err.Source & ControlChars.CrLf & Err.Description
MsgBox(Msg, MsgBoxStyle.Information, "Error")
End If
So this will bring back the error in a MsgBox, however you can just use Response.Write if you want it easier to copy & paste etc..
to get the error description you can do as follows :
Function GetIndexDatabaseConnectionString()
On Error GoTo Errorfound
'your
'function
'body
Exit Function
Errorfound:
With Err
MsgBox "Source: " & .Source & vbCrLf & "Desc: " & .Description, vbCritical, "Error " & CStr(.Number)
End With 'Err
End Function
Related
so im learning to use socket and thread things in the networking software. so far, the software (which is not created by me) is able to chat in multiple group, but i'm tasked to allow user to code whisper feature. However, im stuck in the coding area, which im sure will work if the "if" function work inside "for each" function, anyhow here is my code mainly
Private clientCollection As New Hashtable()
Private usernameCollection As New Hashtable()
clientCollection.Add(clientID, CData)
usernameCollection.Add(clientID, username)
oh and before i forgot, the code above and below is on the server form page
on the client side, i write the code:
writer.write("PMG" & vbnewline & txtReceiverUsername & Message)
then next is the checking part on the server reading the message:
ElseIf message.Substring(0, 3) = "PMG" Then
'filter the message, check who to send to
Dim newMessage As String = message.Substring(3)
Dim messagearray As String() = newMessage.Split(vbNewLine)
Dim receiver As String = messagearray(1)
'0 = "", 1 = receiver, 2 = message
as i write before, clientcollection contain (clientID , connection data*) and usernamecollection contain (clientID, username). In my case, i only have the username data, and i need to trace it until the connection data on clientcollection hash table.
'find realid from usernamecollection, then loop clientcollection
Dim clientKey As String = 0
For Each de As DictionaryEntry In usernameCollection
'''''
'this if part Is Not working
If de.Value Is receiver Then
clientKey = de.Key
End If
'''''
Next de
'match objKey with clientcollection key
For Each dec As DictionaryEntry In clientCollection
If dec.Key = clientKey Then
Dim clients As ClientData = dec.Value
If clients.structSocket.Connected Then
clients.structWriter.Write("PMG" & messagearray(2))
End If
End If
Next dec
End If
so, how do i know that the if part is the wrong one? simply i tried these code before the "next de" code
For Each client As ClientData In clientCollection.Values
If client.structSocket.Connected Then
client.structWriter.Write("PMG" & "receiver:" & messagearray(1))
client.structWriter.Write("PMG" & "loop username: " & de.Value)
client.structWriter.Write("PMG" & "loop key: " & de.Key)
client.structWriter.Write("PMG" & "receiver key:" & clientKey)
End If
Next
the code allow me to check the de.key and de.value. they were correct, however the only thing that did not work is the code inside the "if" area.
Can anyone suggest other code maybe beside "if de.key = receiver"? I've also tried using the if de.key.equal(receiver) and it did not work too
I have a MS Access 2003 Application to port to Visual Basic 6.0 currently. For this purpose, I have written a copy of the usual DLookup commonly used in Access.
Here is the code so far.
Public Function cDLookup(TargetField As String, TargetTable As String, cTCondition As String) As String
'Eigene Implementation von DLookup
Dim result As String
Dim rs As New ADODB.Recordset
Dim SQL As String
On Error GoTo Fehlerbehandlung
'Zusammenbauen der Query
SQL = "SELECT " & TargetField & " FROM " & TargetTable & " WHERE " & cTCondition
Call dbConn
'Initiate Database connection object cn
rs.Open SQL, cn
If (rs.RecordCount = 1) Then
result = cleanString(rs.GetString)
Debug.Print ("[DLOOKUP] Erfolgreich Einen Datensatz gefunden und konvertiert. Output: " & result)
ElseIf (rs.RecordCount > 1) Then
result = "#ErrRC"
Debug.Print ("[DLOOKUP] Es wurden " & CStr(rs.RecordCount) & " Datensätze statt einem festgestellt. Dies ist nicht erlaubt")
Else
result = "#ErrGen"
Debug.Print ("[DLOOKUP] Es ist ein Fehler in der Abfrage aufgetreten")
End If
rs.Close
cDLookup = result
Exit Function
Fehlerbehandlung:
Debug.Print ("[DLOOKUP] Fehler im Ausführen der Prozedur cDLookup()]")
cDLookup = "#Fehler"
Exit Function
End Function
My main issue is with the generated Queries. If a user types garbage that gets inputted into this, there is a runtime error from ADODB when opening the recordset. Can I verify beforehand that a SQL query is not going to do that and catch it to not crash my entire program somehow?
No, not in the way you want. You need to just try to execute it, and handle the error gracefully. You could do something like create a function called "ValidateSQL" with its own error handler, try to execute it, and return false if the query failed. You could even pass the recordset in byref and set it to have the results if it passes.
It's been a long time so forgive syntax mistakes. Something like this:
Function ValidateSQL(ByRef rs as ADODB.Recordset) as Boolean
On Error GoTo Hell
ValidateSQL = True
'open recordset here
Set rs = ....
If False Then
Hell:
ValidateSQL = False
End If
End Function
If you know you're generating trash, why take the trash to the database and wait for the database to blow up to tell you it's trash? Fail Fast is a thing for a reason.
Hitting a database is not free. Even if it's relatively fast, it's orders of magnitude slower than plain code.
Don't get me wrong, I don't mean "validate that the specified field name does indeed exist in the table with the specified name" and "parse that where statement to see if it makes sense".
However, a few sanity-checks will cost much less than a useless trip to the database. You could:
Verify that the table and field names either don't contain any spaces, or are enclosed in square brackets;
Verify that the table and field names aren't empty;
Verify that the WHERE clause doesn't start with "WHERE", and that it's not empty.
If these simple checks pass, then have the database blow up if they're still wrong.
I have a program that is going through the subfolders of a folder and running a stored SQL command on each. I am in the process of writing another module that will automatically check the files before being inputted, but I don't like having my company's test data hinging on a program without any way to know if something errored out. Here is the code I currently have:
Sub openConnection()
Set varConnection = New ADODB.Connection
Set varCommand = New ADODB.Command
varConnection.ConnectionString = "PROVIDER=SQLOLEDB;DATA SOURCE=192.168.1.186,1433;INITIAL CATALOG=Test1; INTEGRATED SECURITY=sspi;"
varConnection.Open
varCommand.CommandText = "importFile"
varCommand.CommandType = adCmdStoredProc
varCommand.ActiveConnection = varConnection
Set varParameter = varCommand.CreateParameter("filePath", adChar, adParamInput, Len(varFolderPath), varFolderPath)
varCommand.Parameters.Append varParameter
varCommand.Execute
varConnection.Close
End Sub
On occasion, the command will error out, causing the data to not be uploaded. How can I catch these SQL errors through Excel VBA in order to handle them appropriately without it being treated as though it had gone through like a normal file?
Note: I don't mind rewriting code- this is all still in alpha.
I guess this might be what you are looking for...
MS Access VBA trapping SQL Server Connection Error
Sub OpenConnection()
On Error GoTo ErrorHandler
// Do your stuff here...
ErrorHandler:
Debug.Print Err.Number & " " & Err.Description
' Or else you could log the error in a file, or even display a message box, whatever...'
End Sub
From the answer provided by fionnuala to the above-linked question.
Thanks in advance for the help. I have no idea what I'm doing wrong and it's becoming very frustrating. First, a little background...
Program: Revit MEP 2015
IDE: VS 2013 Ultimate
I have created a Shared Parameter file and added the parameters in that file to the Project Parameters. These parameters have been applied to Conduit Runs, Conduit Fittings, and Conduits.
I'm using VB.NET to populate the parameters with no issue. After the code runs, I can see the expected text applied in the elements property window. Here is the code used to populate the values:
Populate:
Dim p as Parameter = Nothing
Dim VarName as String = "Parameter Name"
Dim VarVal as String = "Parameter Value"
p = elem.LookupParameter(VarName) <-- elem is passed in to the function as an Element
If p IsNot Nothing Then
p.Set(VarVal)
End if
Here's where I run into the error. When I attempt to retrieve the value, I am able to get the parameter by the parameter's definition name, but the value is always blank. Here is the code used to retrieve...
Try
For Each e As Element In fec.OfCategory(BuiltInCategory.OST_ConduitRun)
sTemp = sTemp & "Name: " & P.Definition.Name & vbCrLf & "Value: " & P.AsString & vbCrLf & "Value As: " & P.AsValueString & vbCrLf & vbCrLf
sTemp2 = sTemp2 & "Name: " & GetParamInfo(P, doc)
Next
MessageBox.Show(sTemp)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
The message box shows all of the parameter names correctly, and for the Revit parameters it gives me a value. The Shared parameters, however, only show the parameter names, the values are always blank. Is there another way that I'm supposed to be going about this? Oddly, I'm able to see the shared parameter values if I use a reference by user selection like so...
Dim uiDoc As UIDocument = app.ActiveUIDocument
Dim Sel As Selection = uiDoc.Selection
Dim pr As Reference = Nothing
Dim doc As Document = uiDoc.Document
Dim fec As New FilteredElementCollector(doc)
Dim filter As New ElementCategoryFilter(BuiltInCategory.OST_ConduitRun)
Dim sTemp As String = "", sTemp2 As String = ""
Dim elemcol As FilteredElementCollector = fec.OfCategory(BuiltInCategory.OST_ConduitRun)
Dim e As Element = Nothing, el As Element = Nothing
Dim P As Parameter
pr = Sel.PickObject(ObjectType.Element)
e = doc.GetElement(pr)
For Each P in e.Paramters
sTemp = sTemp & "Name: " & P.Definition.Name & vbCrLf & "Value: " & P.AsString & vbCrLf & "Value As: " & P.AsValueString & vbCrLf & vbCrLf
sTemp2 = sTemp2 & "Name: " & GetParamInfo(P, doc)
Next
MessageBox.Show(sTemp)
With the method above, when the user selects the object directly, I can see the values and the names of shared parameters. How are they different?
Is there some sort of binding that I should be looking at when the value is set to begin with? Thanks in advance for everyone's help.
Regards,
Glen
Holy Bejeesus... I figured it out, but I'm not sure why the methods are that different from each other... if anyone had any insight, that'd be great.
I wanted to post the answer here, just in case anyone else is fighting with the same thing, so... you can see the method I was using to try to read the parameters above. In the method being used now there are only a couple of things that are different... 1) An element set... 2) An active view Id was added as a parameter to the FilteredElementCollector... 3) A FilteredElementIterator was implemented.
As far as I can tell it's the iterator that's making it different... can anyone explain what it's doing differently?
Below is the method that actually works...
Public Sub Execute(app As UIApplication) Implements IExternalEventHandler.Execute
Dim prompt As String = ""
Dim uiDoc As UIDocument = app.ActiveUIDocument
Dim doc As Document = uiDoc.Document
Dim ElemSet As ElementSet = app.Application.Create.NewElementSet
Dim fec As New FilteredElementCollector(doc, doc.ActiveView.Id)
Dim fec_filter As New ElementCategoryFilter(BuiltInCategory.OST_Conduit)
fec.WhereElementIsNotElementType()
fec.WherePasses(fec_filter1)
Dim fec_i As FilteredElementIterator = fec.GetElementIterator
Dim e As Element = Nothing
fec_i.Reset()
Using trans As New Transaction(doc, "Reading Conduit")
trans.Start()
While (fec_i.MoveNext)
e = TryCast(fec_i.Current, Element)
ElemSet.Insert(e)
End While
Try
For Each ee As Element In ElemSet
GetElementParameterInformation(doc, ee)
Next
Catch ex As Exception
TaskDialog.Show("ERROR", ex.Message.ToString)
End Try
trans.Commit()
End Using
End Sub
At any rate, thanks for any help that was offered. I'm sure it won't be the last time that I post here.
Regards,
Runnin
I am using this code and getting error of type mismatch, runtime error '13'
Error is in line which is marked below, And specifically error is due to where condition (prereq.paid=" + rs1!paid + " ") in query...
rs1.Open "select name,nposts,postad.paid as paid from ad,post,postad where ad.adid = " +
cmbAdno.Text +
" and ad.adid=postad.adid and postad.pid=post.pid ", con, adOpenDynamic,
adLockOptimistic
While Not rs1.EOF
cmbTitle.AddItem (rs1!Name)
rs1.MoveNext
Wend
rs1.MoveFirst
cmbTitle.Text = rs1!Name
txtNposts.Text = rs1!nposts
If IsNumeric(rs1!paid) Then
MsgBox (rs1!paid + 1)
End If
**rs2.Open "select title from postad,prereq where postad.paid = prereq.paid and prereq.paid=" +
rs1!paid + " ", con, adOpenDynamic, adLockOptimistic**
While Not rs2.EOF
lstPrereq.AddItem (rs2!Title)
rs2.MoveNext
Wend
rs2.Close
rs1.Close
Whew, that code needs some work!
The plus operators are the culprit here though. You can easily verify this with a small test case.
Dim ADO_Field_Value As Variant
Dim S As String
ADO_Field_Value = True
On Error Resume Next
S = "text" + ADO_Field_Value + ""
If Err Then MsgBox "Plus failed, err " & CStr(Err)
Err.Clear
S = "text" & ADO_Field_Value & ""
If Err Then MsgBox "Amp failed, err " & CStr(Err)
If you run this the "+" yields an error 13 while the "&" works as expected.
Use the ampersand for concatenation. The plus only sorta, kinda works for backward compatibility with ancient times. Using it requires the compiler to guess at your intent in order to resolve the soft overloading of the operator.
Your "Null hack" concatenting an empty String to the .Value isn't particularly clever. If rs1 has a Null there you end up with a SQL syntax error, unless you use "+" which gets you an error 94.
ADO Field values are safer to access by explicitly using .Value instead of letting the compiler guess you want the default property of the Field. While/Wend is obsolete, and what's with those extraneous parentheses?
You are asking the compiler to do things it probably shouldn't in this code.
is rs1!paid a boolean in the database? if so, maybe there is an issue with the concat to make the query string.
In the old days, when i used VB6 i never accessed fields like that. I used something like rstRecordSet.Fields(0) or rstRecordSet.Fields("field1") but that should not be the problem if the field exists.
Create a string before and pass it the concatenation of the query and verify that it gets filled.
Also, you have "...postad.paid as paid...", why? you dont need to rename the field there...