I have this code that I am using in visual studio 2012 to populate a combobox from data in a sql database. Every time I try to debug it I get the exception at the for loop of a null reference exception. I am hoping someone can help me figure out what it is I am missing here.
Private Sub StationList_Click(sender As Object, e As EventArgs) Handles StationList.Click
Dim cn As New OleDbConnection
cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\hendera2\Desktop\StationEquip.accdb"
Dim Mystr As String = "SELECT DISTINCT Location FROM StationEquipment"
Dim Myadapter As OleDbDataAdapter
Dim Mydataset As New DataSet()
Try
cn.Open()
Myadapter = New OleDbDataAdapter(Mystr, cn.ConnectionString)
Myadapter.Fill(Mydataset, Mystr)
Dim dr As DataRow
For Each dr In Mydataset.Tables("StationEquipDataSet").Rows
Me.StationList.Items.Add(dr("Location"))
Next
cn.Close()
Catch ex As Exception
MsgBox("Cannot Open connection")
End Try
End Sub
Change the "StationEquipDataSet" data table name to "StationEquipment"
You're mismatching the table name, this is causing the null reference when you're trying to access the rows of this table, because it doesnt exists
Obviously I can't see your database, or the records it's pulling, but I would try adding this to elemenate the possibility of trying to reference a null value:
If Mydataset.Tables("StationEquipDataSet").Rows.Count > 0 Then
For Each dr In Mydataset.Tables("StationEquipDataSet").Rows
Me.StationList.Items.Add(dr("Location"))
Next
End If
I believe you got the name wrong in the Mydataset.Tables("StationEquipDataSet") expression.
To find out whether the dataset really does contain your table, and to find out what would be the correct name to use as index, you could try to insert these lines just before the loop:
Console.WriteLine(MyDataSet.Tables.Count);
for (var i = 0; i > MyDataSet.Tables.Count;i++)
{
Console.WriteLine(MyDataSet.Tables[0].TableName);
}
This would for instance write the amount of tables and the table names to the console.
Related
I get Operation is not allowed when the object is closed error.
Why I do get this error?
[Error location][2]
There is nothing wrong with the connection.
I can do SQL queries on the same cmd connection and have no problems with them.
Only this query messes me up.
I usually don't use Set search path or table short names, but just incase got
into very detail this time.
When I run the same query in PostgreSQL I get the result:
[postgres output for the same SQL query][1]
I have been digging around google for hours and I can't find any answers.
Does it have to do something with drivers?
How do I know what driver I use for excel?
What driver I should use?
How I change driver?
[References I use][3]
https://i.stack.imgur.com/R4nLe.png
https://i.stack.imgur.com/k4uJo.png
https://i.stack.imgur.com/Ytrlk.png
CODE
Public Function getDBArray(cmd, strSQL)
Dim recordID As Long, recordAmount As Long, totalFields As Integer, fieldID As Integer
Dim rs As New ADODB.Recordset
Set rs = CreateObject("ADODB.Recordset")
cmd.CommandText = strSQL '' << this is the strSQL i copy pasted directly to pgadmin and it worked
Set rs = cmd.Execute
totalFields = getTableAmount(rs.Fields)
recordAmount = getTableAmount(rs) ' << error in this function
recordID = 0
Apparently I was not suppose to used SET SEARCH PATH
I am having a terrible time trying to get the most simple code to execute consistently in an Excel VBA module.
I'm just trying to assign the value of a field (column) in DB2 to a variable in the module. I've tried the following:
Connection:
Dim odbcName as String
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strCmd As String
'ACME is the name of the ODBC connection I've established and verified/validated.
conn.Open("ACME")
strCmd = "SELECT UNIQUEID, MARKET, SECTOR, CLIENTID FROM PROJECTINFO WHERE UNIQUEID=1234567"
rs.Open Source:=strCmd, ActiveConnection:=conn, CursorType:=adOpenDynamic, LockType:=adLockOptimistic
All is good to that point. The next bit of code is:
If rs.EOF then
'Do some work to add a record if it doesn't already exist - this works fine.
Else
Dim sqlMarket as String
sqlMarket = rs.Fields("MARKET").Value
End If
I also tried:
sqlMarket = rs!MARKET
Both of those attempts, ON THAT LINE where I was attempting to assign a local variable the contents of the MARKET field in the recordset, caused it to crash. I mean, the entire workbook closes, then Excel reopens and tries to open the worksheets, but the module has crashed completely.
Ultimately, my intent is to check all the fields in the recordset against another set of data (in another Excel workbook), and if anything has changed, to update the DB2 recordset. But right now, I can't even seem to LOOK AT the contents of the DB2 recordset without Excel crashing.
Can anyone offer some advice as to what I'm either doing wrong, or what I'm missing?
Excel 365 (Version 1908) 64-bit
IBM DB21085I 64-bit (SQL11050 with level identifier 0601010F)
DB2 v11.5.0.1077
Windows 10 64-bit Version1909 (Build 18363.900)
my question about import excel to datagridview but there is an extra case.
I have also a oledb database with store code and store names.
I want it to show only store codes from db that are in the database after imported.
my codes here;
Dim conn As OleDbConnection
Dim dtr As OleDbDataReader
Dim dta As OleDbDataAdapter
Dim cmd As OleDbCommand
Dim dts As DataSet
Dim excel As String
Dim OpenFileDialog As New OpenFileDialog
OpenFileDialog1.FileName = ""
OpenFileDialog1.InitialDirectory = My.Computer.FileSystem.SpecialDirectories.Desktop
OpenFileDialog1.Filter = "All Files (*.*)|*.*|Excel files (*.xlsx)|*.xlsx|CSV Files (*.csv)|*.csv|XLS Files (*.xls)|*xls"
If (OpenFileDialog1.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK) Then
DataGridView1.Columns.Clear()
Dim fi As New FileInfo(OpenFileDialog1.FileName)
Dim FileName As String = OpenFileDialog1.FileName
excel = fi.FullName
conn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excel + ";Extended Properties=Excel 12.0;")
dta = New OleDbDataAdapter("Select * From [Sheet1$]", conn)
dts = New DataSet
dta.Fill(dts, "[Sheet1$]")
DataGridView1.DataSource = dts
DataGridView1.DataMember = "[Sheet1$]"
conn.Close()
End If
firstly sorry for my terrible english :)
images as follows;
Main Form
Store List Form
I want only the ones in the store list to be displayed in datagrid.. :\
It's not exactly clear what your current presentation/display looks like, what the problem is, and what your desired presentation/display should look like. But you have asked about selecting only one part of the data you are importing, which is presumably found in only one column of the imported Excel data.
When the datatable is created, it has the columns and rows from the Excel worksheet. The columns will be data from the first row, and the rows will be the records from the succeeding rows in the worksheet. You can access both the header data and the row data easily. The code below is VERY rough but for you to see how to gain access to the data in the datatable which you have already very successfully imported in the limited code shown above.
Dim columns = datatable.Columns
Dim rows = datatable.Rows
Dim columns1 = columns(0)
Dim rows1 = rows(0)
Dim element1 = rows1(0)
Columns will have all the headers, so you can locate the column with the store codes or store names. Then the rows will have the data for each store. So above, rows1 is the first row of data and element1 is the data in that row from columns1, and so on. The (0) is the index into the respective collections.
You will, of course, have to write code to extract the data you want and if necessary eliminate duplicates, but the data is all there already.
Hopefully getting the data into a list and then sorting, filtering and selecting the data should be relatively straightforward, but if not, add a comment. That's kind of a different problem. You asked about getting only the store codes.
Added: Based on your additional images and explanation, you are looking to perform an SQL INNER JOIN operation. From the w3schools.com page on SQL INNER JOIN, "The INNER JOIN keyword selects all rows from both tables as long as there is a match between the columns." This is something you will have to study and learn, but it should provide what you need in this case. You will need to define and construct both tables and then perform the JOIN.
And, by the way, you could also follow the link provided in the first comment by T.S., and if that solves your problem, it's a far simpler solution.
I'm trying to expose the column names from excel in a vb.net application. The code looks like this.
Dim EXCEL_CONNECTION_TEMPLATE As String =
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=YES;'"
Using con As OleDbConnection = New OleDbConnection(String.Format(EXCEL_CONNECTION_TEMPLATE, savePath))
con.Open()
Dim schema As DataTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, Nothing)
DoStuffWith(schema)
End Using
After execution i get an exception throwed by GetOleDbSchemaTable:
The Microsoft Jet database engine could not find the object
''sheetname $'Print_Area'. Make sure the object exists and that you
spell its name and the path name correctly.
System.Data.OleDb.OleDbException
It looks like, that GetOleDbSchemaTable has some problem with the sheetnames if they contains space and has print area defined with it on the same time.
Tried to supply parameters like:
Dim schema As DataTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, New Object() {Nothing, Nothing, "sheetname $"})
This way it didn't throwed the exception but returned with no value.
Any tip / workaround / suggestion is welcomed. And it's obviously not an option to ask the users not to include space and print area in the excel file they uploads.
Found the solution.
It seems that if any of the sheet names in the uploaded excel file contains space, the oledb wraps it between single quote. This seems to working now:
Dim schema As DataTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, New Object() {Nothing, Nothing, "'sheetname $'"})
I have one problem. I need to get the excel sheet name in a work book, which looks on the very left sheets tab -the first one from my point of view.
I am using this code:
public static string GetFirstExcelSheetName(OleDbConnection connToExcel)
{
DataTable dtSheetName =
connToExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
List<String> lstExcelSheet = new List<string>(dtSheetName.Rows.Count);
foreach (DataRow row in dtSheetName.Rows)
lstExcelSheet.Add(row["TABLE_NAME"].ToString());
return lstExcelSheet[0];
}
The problem here is it is returning the rows not in the visual tab order but in a very different order - most probably the row created date.
How can it be possible to get the sheetnames table ordered according to their tab order so that I can easily get the 1st excel sheet name?
Thanks,
kalem keki
It should be the zero-th item in the workbooks(?) collection.
I think you have the right index, wrong collection.
Sorry, didn't notice you're using the rows collection of a datatable.
That's a different problem.
How do you create the datatable?
You might have to change the sort property of the dataview.
Dim dtSheetnames As DataTable = oleDBExcelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "TABLE"})
Dim FirstSheetName As String = dtSheetnames.Rows(0)!TABLE_NAME.ToString
The row 0 is not the first sheet in the excel file, rows are sorted by alphabetical order in this collection :/
I recommend using the NPOI library (http://npoi.codeplex.com/) rather than OleDB to retrieve data (including metadata) from Excel.
IIRC, OleDB will also fail for sheet names that include spaces or dollar signs.
OleDbConnection oconn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Session["path"].ToString() + "; Extended Properties=Excel 12.0;Persist Security Info=False;");
oconn.Open();
myCommand.Connection = oconn;
DataTable dbSchema = oconn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (dbSchema == null || dbSchema.Rows.Count < 1)
{
throw new Exception("Error: Could not determine the name of the first worksheet.");
}
string firstSheetName = dbSchema.Rows[0]["TABLE_NAME"].ToString();