Nested With Statement Crashes - vb.net-2010

After Visual Studio 2010 locked up earlier today, a code segment that contains a nested With statement no longer works, and locks up, and I have to use Task Manager to terminate VS-2010.
I had a block of code as follows:
With cmd ' OleDbCommand object
With .Parameters '<------- locks up when executing this line
.AddWithValue("#Parm1", Parm1Value)
.AddWithValue("#Parm2", Parm2Value)
' Etc.
End With
.ExecuteNonQuery()
End With
This ran fine, until VS locked up earlier. I had to delete the SUO files from the directory so that VS would not complain when trying to open the documents I had opened previously. But then this nested With-statement stopped working.
However, the following two variations of the code work fine:
With cmd
With cmd.Parameters '<--- with cmd explicitly specified
.AddWithValue("#Parm1", Parm1Value)
.AddWithValue("#Parm2", Parm2Value)
' Etc.
End With
.ExecuteNonQuery()
End With
and
cmd.Parameters.AddWithValue("#Parm1", Parm1Value)
cmd.Parameters.AddWithValue("#Parm2", Parm2Value)
cmd.ExecuteNonQuery()
Any nested With statement that leverages the outer With statement fails the same way (i.e. does not have to be in conjunction with OleDb objects) I did a small test project that did a With on the form object, and a nested With on a sub-object ... same results: it locked up.
I ran the VS-2010 installation to do a repair, and it still behaves this way. Rebooting also does not fix the problem.
I can just code that a different way, but I shouldn't have to, and secondly, who knows what else got messed up when VS crashed that first time?!!
I was hoping to not have to do a full uninstall/reinstall of VS-2010.
Has anyone else seen this problem?

Were you working on this solution/project when VS2010 crashed?
Were you confronted with a project file recovery option before and/or after you removed the SUO file?
As a point of interest, test initializing Anonymous objects using the with statement:
Dim cust0 = New With {.Name = "Toni Poe", .City = "Louisville"}
Have your tried a 'Clean' & 'Rebuild' on your solution.
Try creating a new solution/project and testing a nested with statement on a new OleDbCommand object.
Though, you'll probably feel better with a clean install of VS2010. I suspect your solution is corrupt, not vs2010.

Related

Access not exiting

Recently, my Access .mdb database started intermittently not allowing Access (both Access 2003 and 2007) to quit. If I quit (whether by pressing the X button or from the menu, then it closes the database and appears to exit Access, as well, but then it suddenly reappears (without any database open). The only way for me to exit at that point is from the task manager.
There are two significant changes that I did recently that might be related. 1) I started using the WinSCP .Net assembly to access an ftp server, which I had to install and register for COM from the instructions here. 2) I started using ODBC, first as a linked table, and then from VBA ADO code (see this). I doubt that this second change is causing this problem because I've had the problem both when I was using the linked tables and when with ADO.
This doesn't happen every time I open the database, and I haven't noticed a pattern. What could be causing this strange problem?
Edit - I found the root of the problem. By breaking my ftp download code at various points and seeing whether it will exit, I narrowed it down to the following:
Dim PDFFolders As Recordset
Set PDFFolders = CurrentDb.OpenRecordset("PDFFolders")
Dim syncOptions As TransferOptions
Set syncOptions = New TransferOptions
syncOptions.filemask = "*/*.pdf"
On Error Resume Next 'In case it doesn't exist
Do While Not PDFFolders.EOF
sess.SynchronizeDirectories SynchronizationMode_Local, info!RTFFolder, _
info!BasePDFFolder & "/" & PDFFolders!Name, False, , , _
syncOptions
PDFFolders.MoveNext
Loop
PDFFolders.Close
Set syncOptions = Nothing
Set PDFFolders = Nothing
On Error GoTo 0
If it runs the sess.SynchronizeDirectories statement, then access won't exit, otherwise it does. Looks to me like a bug win WinSCP.
I can do other things like downloading files, creating directories, etc. with no problem, but when it gets to this statement, it doesn't exit access afterwards.
Sticky instances of Access usually result from hanging object references.
If Access hangs the way you described, I would suspect a nasty circular reference.
To investigate on circular references, you basically have two options:
Inspect your code on circular dependencies - That might become tedious and not so easy. But if you know your code base deeply, you might have suspects where to look first.
Add logging to your code - In case you cannot spot the problem via inspection alone, you can consider adding consequent logging of object creation/deletion (through Class_Initialize/Class_Terminate). For larger code bases using classes heavily, this is a good investment to start with.
If your problem is with classes where you cannot control the code (as is your case), you might consider using that external classes only through wrapper classes where you can log creation/deletion. Of course in tricky cases, termination of the wrapper class does not mean termination of the wrapped class.
BTW, I strongly recommend to make sure to set every object reference explicitly to Nothing ASAP:
Set MyObj = GetMyObject()
' Proceed with coding here later
' First write the following line
Set MyObj = Nothing
Special thoughts have to be given in the case of local error handling to make sure to set the reference to Nothing in either case.
A good way to ensure this is using a With-block instead of an explicit variable (if the usage pattern allows to):
With GetMyObject()
' Use the object's members here
End With
With this pattern you save declaring the local variable and can be sure that the object reference does not survive the current method.
I still think it's a bug in WinSCP, but I found a workaround. I noticed that it only happened if I took the information from a table in the database, and not if I put in a hard-coded string. So I just added & vbNullString, which concatenates a blank string, which changes the data type from a Field to a String, and now it doesn't happen anymore.

ODBC reading of BMC AR System / Remedy data to VS2010/VB .NET

Edit MY goal is this, I need to do read data from a Remedy Database using a VB .Net app. /Edit
I am trying to read data from the AR System ODBC driver in a VS 2010 VB windows form.
I have added a connection in the data connections via , a system dsn, connection string pulled from a working excel data pull, and built a connection string based via the wizard.
I can test connection, and it comes back 'test connection succeeded'.
When I click ok and the Data connection goes to my server explorer, it expands to tables, view, and procedures and viewing/refreshing those causes errors such as:
Column 'Table_Cat' does not belong to table Tables.
Error [im00][ar system odbc driver] not supported
I am aware there is the api out there, however this has a problem in that the api acts like a login session from the client, which limits you to one login session. This not feasible for the task at hand as the user needs to remain logged into remedy, and the app I'm writing will be read only for data.
The goal is a billboard app that will display certain tickets, kind of like a stock ticker.
There will be no editing of ticket data from remedy, I just need to read the tickets and provide tallies and alerts for our helpdesk.
It seemed so easy when I sat down, but now 4 hours later and a mind numbing amount of irrelevant google results, I'm almost wondering if I'm going to have to report back that it cannot be done with out the api and creating more remedy accounts. Not having to create additional remedy accounts was part of of the request put to me.
Tags: Visual Studio 2010 BMC AR System Remedy ODBC VB.NET
Update
So I have done the code by hand and now seem a few steps forward, but still blind.
Ok, so if i export my excel query it looks like this from the dqy file
export.dqy
DRIVER={AR System ODBC Driver};ARServer=xxxxxx;ARServerPort=xxxxx;UID=xxxx;PWD=xxxx;ARAuthentication=;SERVER=NotTheServer
SELECT "EN:HelpDesk"."Company Name", "EN:HelpDesk"."Call Status", "EN:HelpDesk"."Caller Region", "EN:HelpDesk"."Next Action", "EN:HelpDesk"."Detailed Description(FTS)", "EN:HelpDesk".Device, "EN:HelpDesk"."Submitted-by", "EN:HelpDesk".Impact, "EN:HelpDesk"."Arrival Time", "EN:HelpDesk"."Call Id", "EN:HelpDesk".Market FROM "EN:HelpDesk" "EN:HelpDesk" WHERE ("EN:HelpDesk"."Call Status"<>'Closed') AND ("EN:HelpDesk"."Submitted-by"<>'nis') AND ("EN:HelpDesk".Impact='High') AND ("EN:HelpDesk".Market='DCIN') AND ("EN:HelpDesk"."Caller Region"<>'UK')
First off, these quotes look wrong to me, but it seems to work because if I leave them, executing the command doesn't fail, however it doesn't return data to my data grid view in vb.
Second the EN:Helpdesk looks odd to me but again same results as the quotes.
I have tried changing the quotes to brackets [ ] but receive errors once I do.
Here is my code:
VB Code
Imports SystemM My goal
Imports System.Data
Imports System.Data.Odbc
Imports System.Data.SqlClient
Sub Main()
Dim sql As String
Dim connectionString As String = "DRIVER={AR System ODBC Driver};ARServer=xxx;ARServerPort=xxx;UID=xxx;PWD=xxx;ARAuthentication=;SERVER=NotTheServer"
sql = "SELECT ""EN:HelpDesk"".""Company Name"", ""EN:HelpDesk"".""Call Status"", ""EN:HelpDesk"".""Caller Region"", ""EN:HelpDesk"".""Next Action"", ""EN:HelpDesk"".""Detailed Description(FTS)"", ""EN:HelpDesk"".Device, ""EN:HelpDesk"".""Submitted-by"", ""EN:HelpDesk"".Impact, ""EN:HelpDesk"".""Arrival Time"", ""EN:HelpDesk"".""Call Id"", ""EN:HelpDesk"".Market FROM EN:HelpDesk WHERE (""EN:HelpDesk"".""Call Status""<>'Closed') AND (""EN:HelpDesk"".""Submitted-by""<>'nis') AND (""EN:HelpDesk"".Impact='High') AND (""EN:HelpDesk"".Market='DCIN') AND (""EN:HelpDesk"".""Caller Region""<>'UK')"
Dim bindingSource1 As New BindingSource()
Me.SQLDS_reportresults.DataSource = bindingSource1
Dim myAdapter = New OdbcDataAdapter(sql, connectionString)
Dim commandBuilder As New OdbcCommandBuilder(myAdapter)
Dim table As New DataTable()
table.Locale = System.Globalization.CultureInfo.InvariantCulture
myAdapter.Fill(table)
bindingSource1.DataSource = table
Me.SQLDS_reportresults.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader)
End Sub
Project is a windows forms with a button to activate main(), a textbox (textbox1) and a datagridview(SQLDS_reportresults).
As the code stands, this causes no errors, but my datagridview never populates. Since there are no errors, I'm inclined to think my connection is working , and that my command is being executed,making my problem lay in code, however given the funky use of quotes and en:helpdesk in the sql command, I'm also concerned that is malformed and causing the where portion to return no results.
Anyone have any suggestions / ideas?
I need a way to display these results in app, and right now I don't care how just as long as I can see some data at all.
I've been googling and looked at the vb examples in the api zip but that is not related to opening a odbc connection and I found that of little help in my research.
I almost feel like I'm missing something simple or obvious.
When i run odbcad32.exe my ar system odbc driver shows 7.00.01.02 which is what I assume is installed on everyones machines as I used the remedy install set provided to me by the IT/Software admins to build this dev box.

How to release MS Access LDB lock file after created it

sorry for long text.
Problem: I have difficulty in removing the LDB generated by the "CREATE" method of ADOX in the following code segment. Please provides some hints/pointers to the solutions, and thanks.
Aims: Create (on the fly) a new access database and then export data (says Arena modules) to that newly created database.
Expected: The newly created access database should be able to be used by some external operations, say Access.exe, after the end of the subroutine and without exiting the current VB program.
I tested that the "Arena code" do nothing about the create/release of the ldb file.
I tested the "Exclusive Mode" in connection string, but the access file is still locked by the vb program.
I tested under both inside the VB environment, and directly invoke the generated from Explorer, and same results.
Other database formats is not the options to me. (due to Arena export limit)
It is not a web app.
Code:
Sub Method1()
Dim logs As New System.Collections.Generic.List(Of String)
Dim arenaApp As Arena.Application = Nothing
Try
logs.Add("Creating access database")
Try
Dim cat As New ADOX.Catalog
cat.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=new.mdb;Jet OLEDB:Engine Type=5")
cat = Nothing
Catch ex As Exception
logs.Add(ex.Message)
logs.Add(ex.StackTrace)
Finally
logs.Add("End creating access database")
End Try
'Opening Arena model"
arenaApp = New Arena.Application()
arenaApp.Models.Open(fileName)
arenaApp.ActiveModel.ExportModules("", "new.mdb", "TableName", "", Arena.smExportType.smExportAll)
Catch ex As Exception
logs.Add(ex.Message)
logs.Add(ex.StackTrace)
Finally
...
End Try
End Sub
Platform:
Windows 7 64bit, Office 2010 (32)
VB 2010 express
Lib: MS ADO Ext. 2.8 for DDL and Security
What about closing the mdb after creation, then reopening it ?
I am not a VS expert, but in Access, many things in "Design mode" put the mdb in Exclusive mode...and you can't switch back without closing it first i suspect.
If you want to create a database, its probably simpler to PInvoke SQLConfigDataSource. Then you can connect to it via ADODB, ADO.NET or your VB.NET data access methodology of choice.
I don't have an example of doing it in VB.NET, but this C# class and this powershell script demonstrate how to call the function.
I know it's an old question. I encountered exactly the same issue today. Some comments ask why use ADOX, that's because first, it's from legacy code, and second, I didn't find any other ways to dynamically create mdb file.
In VB6, whenever you set adox = Nothing, this com object will be released immediately and so is the ldb file.
In .Net, you have to rely on GC to collect the adox before ldb file is unlocked.
So, I made the following trick. I know it's ugly, but I didn't find any other ways, and at least my trick worked.
Dim t As New Thread(
Sub
'All adox code should be here
'....
'....
adox = Nothing
End Sub
)
t.Start()
t.Join()
t = Nothing
GC.Collect()
Sleep(50)

sqlite in vb.net, can't find table even though it exists

I'm using the following code (System.Data.SQLite within VB.net):
Dim SQLconnect As New SQLite.SQLiteConnection()
Dim SQLcommand As SQLiteCommand
SQLconnect.ConnectionString = "Data Source=vault.db;"
SQLconnect.Open()
SQLcommand = SQLconnect.CreateCommand
SQLcommand.CommandText = "INSERT INTO entries VALUES ('" & appinput.Text & "','" & userinput.Text & "','" & passinput.Text & "')"
SQLcommand.ExecuteNonQuery()
SQLcommand.Dispose()
SQLconnect.Close()
Me.Hide()
I get an error back that says it can't find the table "entries"
I know the table exists because I can write to it via the command line through sqlite and through Autoit and can see it and edit it in the SQLite browser when I open the database. I don't understand why VB can't see it (I know it sees and opens the database file just fine). Any ideas?
Most likely your problem is with relative paths (directories).
sqlite will create a database file if it does not exist so you will never get a "db file not found message". The first indication of an incorrect path is "table missing".
My personal experience is that although it goes against my programmers instinct is to alway use an absolute (fully qualified) path/file name for an sqlite database.
If you put in the full file location like "/var/myapp/vault.db" you should be OK.
If this is likly to move around store pick up the file name from a properties/config file -- 'config file not found' is much easier to deal with than "table not found".
Argh! There are 3 big issues in that code. Please update it like this to fix two of them:
Using cn As New SQLite.SQLiteConnection("Data Source=vault.db;"), _
cmd As New SQLiteCommand("INSERT INTO entries VALUES (#AppInput, #UserInput, #PassInput)", cn)
cmd.Parameters.AddWithValue("#AppInput", appinput.Text);
cmd.Parameters.AddWithValue("#UserInput", userinput.Text);
cmd.Parameters.AddWithValue("#PassInput", passinput.Text);
cn.Open()
cmd.ExecuteNonQuery()
End Using
This will prevent sql injection by parameterizing your query instead of substituting values directly and prevent db locking issues by making sure your connection is disposed properly, even if an exception is thrown.
The third problem is that you should NEVER store plain-text passwords in your database (or anywhere else for that matter). Go read up on how to hash values in .Net and hash and salt your password before storing or comparing it.
Once you've done that re-test your code to see if you still get the same errors reported as before. We need to make sure this didn't solve the problem or introduce something new. Then we can start addressing the missing table issue, perhaps by checking your connection string.
I had a similar error with SQLite (via .Net) refusing to believe the table existed, even though direct access confirmed it was there. The error could be produced only on one individual machine and not others. Hard coding the path didn't seem to fix the problem. The fix was either to run the program as Administrator or change the DB file to be available to Everyone. Apparently the .Net assembly raises a missing table error when the actual problem is access restrictions.

Intermittent error when attempting to control another database

I have the following code:
Dim obj As New Access.Application
obj.OpenCurrentDatabase (CurrentProject.Path & "\Working.mdb")
obj.Run "Routine"
obj.CloseCurrentDatabase
Set obj = Nothing
The problem I'm experimenting is a pop-up that tells me Access can't set the focus on the other database. As you can see from the code, I want to run a Subroutine in another mdb. Any other way to achieve this will be appreciated.
I'm working with MS Access 2003.
This is an intermittent error. As this is production code that will be run only once a month, it's extremely difficult to reproduce, and I can't give you the exact text and number at this time. It is the second month this happened.
I suspect this may occur when someone is working with this or the other database.
The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database.
Maybe, it's because of the first line in the 'Routines' code:
If vbNo = MsgBox("Do you want to update?", vbYesNo, "Update") Then
Exit Function
End If
I'll make another subroutine without the MsgBox.
I've been able to reproduce this behaviour. It happens when the focus has to shift to the called database, but the user sets the focus ([ALT]+[TAB]) on the first database. The 'solution' was to educate the user.
This is an intermittent error. As this is production code that will be run only once a month, it's extremely difficult to reproduce, and I can't give you the exact text and number at this time. It is the second month this happened.
I suspect this may occur when someone is working with this or the other database.
The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database.
Maybe, it's because of the first line in the 'Routines' code:
If vbNo = MsgBox("Do you want to update?", vbYesNo, "Update") Then
Exit Function
End If
I'll make another subroutine without the MsgBox.
I've tried this in our development database and it works. This doesn't mean anything as the other code also workes fine in development.
I guess this error message is linked to the state of one of your databases. You are using here Jet connections and Access objects, and you might not be able, for multiple reasons (multi-user environment, unability to delete LDB Lock file, etc), to properly close your active database and open another one. So, according to me, the solution is to forget the Jet engine and to use another connexion to update the data in the "other" database.
When you say "The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database", I assume that the role of your "Routine" is to update some data, either via SQL instructions or equivalent recordset updates.
Why don't you try to make the corresponding updates by opening a connexion to your other database and (1) send the corresponding SQL instructions or (2) opening recordset and making requested updates?
One idea would be for example:
Dim cn as ADODB.connexion,
qr as string,
rs as ADODB.recordset
'qr can be "Update Table_Blablabla Set ... Where ...
'rs can be "SELECT * From Table_Blablabla INNER JOIN Table_Blobloblo
set cn = New ADODB.connexion
cn.open
You can here send any SQL instruction (with command object and execute method)
or open and update any recordset linked to your other database, then
cn.close
This can also be done via an ODBC connexion (and DAO.recordsets), so you can choose your favorite objects.
If you would like another means of running the function, try the following:
Dim obj As New Access.Application
obj.OpenCurrentDatabase (CurrentProject.Path & "\Working.mdb")
obj.DoCmd.RunMacro "MyMacro"
obj.CloseCurrentDatabase
Set obj = Nothing
Where 'MyMacro' has an action of 'RunCode' with the Function name you would prefer to execute in Working.mdb
I've been able to reproduce the error in 'development'.
"This action cannot be completed because the other application is busy. Choose 'Switch To' to activate ...."
I really can't see the rest of the message, as it is blinking very fast. I guess this error is due to 'switching' between the two databases. I hope that, by educating the user, this will stop.
Philippe, your answer is, of course, correct. I'd have chosen that path if I hadn't developed the 'routine' beforehand.
"I've been able to reproduce this behaviour. It happens when the focus has to shift to the called database, but the user sets the focus ([ALT]+[TAB]) on the first database. The 'solution' was to educate the user." As it is impossible to prevent the user to switch application in Windows, I'd like to close the subject.