Connection with MS Access 2010 via vb.net - vb.net

Dim newRow As DataRow = dt.NewRow
newRow.Item(1) = Student_IDTextBox.Text
newRow.Item(2) = Student_NameTextBox.Text
newRow.Item(3) = Date_of_BirthDateTimePicker.Text
newRow.Item(4) = AddressTextBox.Text
newRow.Item(5) = E_mailTextBox.Text
newRow.Item(6) = AllergiesTextBox.Text
newRow.Item(7) = Emergency_Contact_NumberTextBox.Text
dt.Rows.Add(newRow)
The line
newRow.Item(2) = Student_NameTextBox.Text
gives a error saying:
"String was not recognized as a valid DateTime. Couldn't store <> in Date of Birth Column. Expected type is DateTime."
But I checked the database the second row is the Student name Field.
I think the code is starting to input the student name into the student ID field in the database, The Student Id is the primary key coe this be why it isn't storing the student_IDtextbox data in its specified field?
I realy need help with this my project is due in about 9 days!

the columns index in DataRow class, Similar all indexs in vb.net, its zero-based.
first column is zero, second one and ect.

Related

.Select return wrong length

I'm trying to check if the field data of my DataTable records is set to '0' or '1'. All my local record is saved into local_ds DataTable. Now, the record that I want check is this: 21a956af-f304-4c72-97cf-1ef08e8719fc
for a better vision I paste here the content of my table (that is also the content of my DataTable local_ds):
How you can see the record that I want check have the field data set to 0. Now I perform the research through this code:
Dim local_data = local_ds.Tables(0).Select(String.Format("GUID = '{0}'", "21a956af-f304-4c72-97cf-1ef08e8719fc"), String.Format("data", 1))
The code above use LINQ to take the result, anyway, I pass the GUID field to search and the field data as 1. This code should be return local_data.length equal to 0 but, instead, return 1 and this is wrong, 'cause I want to check only if the field data is 0 or 1. In this example the result should be local_data.length = 0 'cause in the LINQ query I specified clearly that I want find the record with GUID = x and data = 1.
I already know that this record exists in the database, the local_data variable must help me to recognize which type of valorization the data field have.
So, what I did wrong?
No, in the code above, you are not using LINQ.
DataTable.Select is a method available starting from the 1.1 version of NET Framework and exists in four possible overloads.
The one you are using is the one that takes, as first parameter, the WHERE condition and, as second parameter, the SORT order. So you are not really passing a condition WHERE .... AND Data = 1 but the Data=1 it is interpreted as a sort order of some kind.
The correct string for the WHERE parameter should be
Dim where as String = String.Format("GUID = '{0}' AND Data = {1}", _
"21a956af-f304-4c72-97cf-1ef08e8719fc", 1)
Dim local_data = local_ds.Tables(0).Select(where)

Conversion of Varchar to int

Need help! I cannot retrieve data in SQ L, because the value is 100-200
and it says that it needs to be converted it to Integer, but it is Var char data type.
So i think the problem is about the "-", then the error in the code is in
the data table code, so what to do?
Private Sub RetriveData(ByVal ID As String)
If Sql.HasConnection() = True Then
Dim DT As DataTable = Sql.ExecuteDataTable("SELECT (EmpID As varchar), FirstName,MidName,LastName,Gender,BirthDate,CivilStat,Address,ContactNum FROM EmployeeTable Where EmpID=" & ID)
For Each Data As DataRow In DT.Rows
EmpID_Txt.Text = Data(0)
FirstName_Txt.Text = Data(1)
MiddleName_Txt.Text = Data(2)
LastName_Txt.Text = Data(3)
Gender_CB.Text = Data(4)
BirthDate_DTP.Value = Data(5)
CivilStat_CB.Text = Data(6)
Address_Txt.Text = Data(7)
Contact_Txt.Text = Data(8)
Next
Else
MsgBox("System Database Cannot be Connected", MsgBoxStyle.Information)
End If
End Sub
Pass the ID as SQL Parameter to your query:
"SELECT (EmpID As varchar), FirstName,MidName,LastName,Gender,BirthDate,CivilStat,Address,ContactNum FROM EmployeeTable Where Empid=#empid"
Actually, assuming those 100-200 values are in a table somewhere, I would say the error was in the cranium of the developer who decided to use a varchar to store a numeric value :-)
Either that, or the developer who decided to take an otherwise free-form text field and assume it was always going to be a single numeric value.
As to how to fix it, one of those paragraphs simply needs to be worked around. If you want a single numeric value in the table, you should change it to a numeric type field, along the way going through all 100-200 style values and cleaning them up (into, for example, 150).
If you want to be able to store ranges, then your code that processes them is going to have to be more intelligent, such as extracting the lower and upper value from the column and running a loop to process all values within the range, or changing a query from (pseudo-codish query):
where EmpId = ?value?
into:
where EmpId >= ?low? and EmpId <= ?high?
We can't really tell you which is the best solution based on the information provided, this is likely to be a business decision rather than a technical one.
If my assumption is wrong and it's the ID argument (being used in the where clause) to the function RetriveData (sic), then you either need to stop users entering that, or make the code that processes the argument more intelligent (similar to the looping/changed-query suggestion above).

How do i obtain foreign table field using string value for fieldname with reflection and entity framework

I have 2 tables. An asset table that links using a foreign key to a device table.
To get the device_name field of the asset, in linq i would use:
dim device as string = result.device.device_name
The Result object contains the unique record from an earlier linq to entity framework command.
Now I have a need to allow end users to specify their fields they want in a report. I will end up having a string name of the field, so tried using reflection
dim name as string = result.GetType().GetProperty("asset_name").GetValue(result)
This returns the asset_name field so i thought great, i should be able to get the relating foreign table field value.
dim device = result.GetType().GetProperty("device").GetValue(result).GetType.GetProperty("device_name").GetValue(result.device)
This works however i had to specify the object. As i will have other tables linking to the first table, would i have to write additional code to check what object and manually specify? Or am i going into this wrongly? Any help and advice appreciated.
I couldn't find a cleaner solution, so this is how i did it:
dim field as string ="device.device_name"
dim output as string =""
dim subtable as string =""
If field.Contains(".") Then
subtable = field.Substring(0, field.IndexOf("."))
field = field.Substring(field.IndexOf(".") + 1)
End If
If subtable <> "" Then
Select case subtable
Case "device"
If Not IsNothing(result.device.GetType().GetProperty(field)) Then
output = result.device.GetType().GetProperty(field).GetValue(result.device)
End If
End Select
Else
If Not IsNothing(result.GetType().GetProperty(field)) Then
output= result.GetType().GetProperty(field).GetValue(reult)
End If
End If
Return output

InvalidCastException in Linq to entities query

I am making an application for my department at work. I have run into a big problem.
I am trying to get the primary key of a name selected on a ListBox control. This ListBox control is populated from a query from the database when the form loads. Below is the query used to populate the ListBox control.
Dim examinationOfficer As New ExamOfficerPayEntities
Dim findOfficer = From officer In examinationOfficer.Exams_Officer
Order By officer.First_Name Ascending
Select officer.First_Name.ToUpper & " " & officer.Last_Name.ToUpper
lstFullname.DataSource = findOfficer.ToList
lstFullname.DisplayMember = "FullName"
The query works fine and the ListBox is populated as expected. The problem is I am trying to get the value of the primary key of the selected ListBox item. The primary key value I am trying to retrieve is an integer value and it is set as an identity.
Below is a summary of my database.
Table Exam_Officer:
Officer_ID as int which is the primary key and is also set as an identity column
First_Name as nvarchar
last_Name as nvarchar
One other Table is Result_Submitted,
its columns are:
sn as integer primary key and an identity column
Officer_ID as an int and is a foreign key to the Table Exam_Officer
Result_Submitted as nvarchar
Outstanding_Result as nvarchar
This is the code I am trying to use to get the officer_ID from the SelectedItem property of the ListBox control of a Windows form.
Dim selectedOfficer As Exams_Officer = DirectCast(lstFullname.SelectedItem, Exams_Officer)
Dim selectedOfficerID As Integer = selectedOfficer.Officer_ID
The code dosen't work it throws an error on the first line (directcast method)
System.InvalidCastException was unhandled
Message=Unable to cast object of type 'System.String' to type 'EXAMINATION_OFFICER_PAYMENT.Exams_Officer'.
Source=EXAMINATION OFFICER PAYMENT
I am confused and don't know what else to do. Any help is appreciated.
To be honest, I'm surprised it's even displaying at the moment as FullName isn't a property of String. Look at your code:
Dim examinationOfficer As New ExamOfficerPayEntities
Dim findOfficer = From officer In examinationOfficer.Exams_Officer
Order By officer.First_Name Ascending
Select officer.First_Name.ToUpper & " " & officer.Last_Name.ToUpper
You're selecting the full name - so the result of your code is just the names, not the original officers. I suspect you want:
Dim examinationOfficer As New ExamOfficerPayEntities
Dim findOfficer = From officer In examinationOfficer.Exams_Officer
Order By officer.First_Name Ascending
lstFullname.DataSource = findOfficer.ToList
lstFullname.DisplayMember = "FullName"
At that point, you've got a list of officers rather than a list of strings. This is assuming FullName is a property of your officer type though. If it's not, you might want to project to a list where you do the string concatenation in one property, but keep the original officer in another property. For example:
Dim examinationOfficer As New ExamOfficerPayEntities
Dim findOfficer = From officer In examinationOfficer.Exams_Officer
Order By officer.First_Name Ascending
Select New With {
.FullName = officer.First_Name.ToUpper & " " _ & officer.Last_Name.ToUpper,
.Officer = officer
}
lstFullname.DataSource = findOfficer.ToList
lstFullname.DisplayMember = "FullName"
Then later, you'd need to extract the value of the Officer property to get at the officer object itself.
In general the way to do this is to add Officers to your ListBox and override Officer's ToString() method to return FullName, or bind and set DisplayMember to Fullname. Like Jon Skeet, I'm not sure why the code you've posted is working...
Then you can do
Dim selectedOfficer As Exams_Officer = DirectCast(lstFullname.SelectedItem, Exams_Officer)
and Exams_Officer.OfficeID will be okay.
At the moment you are casting a string to an Officer, the above casts an Object to an Officer, which is more likely to work.
Bear in mind however that you need to instance all your officers and that they'll be in memory. So if had a lot of and/or Officer was a hefty object, performance might start to suffer.
The simplest option at that point is a small class / structure with just ID and name in it.

Microsoft Access find field in table with known value

We have a fairly large Oracle database that we are able to connect via Microsoft Access and ODBC with read-only access. We work with a front-end system that does not match the structure behind the scenes and often I need to query the system via Microsoft Access. The problem is that we are not provided any documentation as to structure and the structure needs serious attention. Searching for the field that I need is very time consuming.
With our front end, I'm able to view the values that I want to query, and I know the key fields, but I need to find the field that contains the known value.
If I have a record where I know the value of field "A", and have the value of field "X", is it possible to query field "X"?
Front end shows
Student ID: 12345678
Payments: 23456
Back end
TechID: 12345678
???: 23456
Can I query "???"
You can do this by iterating over the collection of tables, and for each table, the collection of fields.
Open Database
Get all Tables
For Each Table
Get all Fields
For Each Field
If Field type is text ... and
If Field size is not TOO Long ...
Search for string
If found, write to a results bucket
Next
Next
Here is an example of code for cataloging tables (source here)
Public Function GenerateDataDictionary(aDataDictionaryTable As String)
'*** Usage: GenerateDataDictionary("MyDataDictionaryTable")
'*** Extracts the information about the tables for the data dictionary
'*** and inserts it to a table named aDataDictionaryTable
Dim tdf As TableDef, fldCur As Field, colTdf As TableDefs
Dim rstDatadict As Recordset
Dim i As Integer, j As Integer, k As Integer
Set rstDatadict = CurrentDb.OpenRecordset(aDataDictionaryTable)
Set colTdf = CurrentDb.TableDefs
'Go through the database and get a tablename
For Each tdf In CurrentDb.TableDefs
'Do what you want with the table names here.
rstDatadict.AddNew
rstDatadict.Update
rstDatadict.AddNew
rstDatadict![Table] = tdf.NAME
rstDatadict![Field] = "----------------------------"
rstDatadict![Display] = "----------------------------"
rstDatadict![Type] = ""
rstDatadict.Update
rstDatadict.AddNew
rstDatadict![Table] = "Table Description:"
For j = 0 To tdf.Properties.Count - 1
If tdf.Properties(j).NAME = "Description" Then
rstDatadict![Field] = tdf.Properties(j).Value
End If
Next j
rstDatadict.Update
rstDatadict.AddNew
rstDatadict.Update
For i = 0 To tdf.Fields.Count - 1
Set fldCur = tdf.Fields(i)
rstDatadict.AddNew
rstDatadict![Table] = tdf.NAME
rstDatadict![Field] = fldCur.NAME
rstDatadict![Size] = fldCur.Size
Select Case fldCur.Type
Case 1
FieldDataType = "Yes/No"
Case 4
FieldDataType = "Number"
Case 8
FieldDataType = "Date"
Case 10
FieldDataType = "String"
Case 11
FieldDataType = "OLE Object"
Case 12
FieldDataType = "Memo"
Case Else ' Other values.
FieldDataType = fldCur.Type
End Select
rstDatadict![Type] = FieldDataType
For j = 0 To tdf.Fields(i).Properties.Count - 1
If fldCur.Properties(j).NAME = "Description" Then
rstDatadict![DESCRIPTION] = fldCur.Properties(j).Value
End If
If fldCur.Properties(j).NAME = "Caption" Then
rstDatadict![Display] = fldCur.Properties(j).Value
End If
If fldCur.Properties(j).NAME = "Rowsource" Then
rstDatadict![LookupSQL] = fldCur.Properties(j).Value
End If
Next j
rstDatadict.Update
Next i
Debug.Print " " & tdf.NAME
Next tdf
End Function
You can catalog your findings in Access by making a table of field-names which joins to a table of table-names. Then your searches are based on the catalog instead of raw collections.
I reverse-engineered the schema for MAS 90 (with JobOps add-in) this way. There's no map, but I had a read-only ODBC connection which I used in precisely the way you propose. The purchasing accountant would give me a distinctive Product Number and I'd run it through this comprehensive engine. Over time I succeeded in distilling 700 tables comprising 18k fields down to 20 tables and a few hundred fields. That allowed us to export our data.
The answer to your question is simple. No, you cannot do that.
There are two solutions that I can think of. The first is to manually concatenate all the values together and then look for the row that contains the value. This is imperfect, but might work:
select *
from (select t.*, ('|'""col1||'|'||col2+'|' . . .||'|') as allcols
from t
) t
where instr('|23456|', allcols) > 0
This would find any row that has that value in a column. Probably close enough for what you want.
The second is to use UNPIVOT to do essentially the same thing.
I would strongly suggest that you invest a little bit of time to find the mapping between the fields, and then create a view in Oracle that has the field names as seen in the application. It sounds like this would save you a lot of effort in the medium term.