I'm trying to import rows from one db to another, basically it something to do with this SQL:
SELECT * INTO [MSAccess;DATABASE=C:\MainDB.mdb;].[Header] FROM [Header] WHERE ID=9
As it returns this error: Could not find installable ISAM.
Any ideas? To help explain I've added my code:
Dim sSQL As String
Dim iCertMainNo As Integer
Dim cnLocal As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & App_Path() & "LocalDB.mdb;")
Dim cnMain As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & My.Settings.MainDB & ";")
cnLocal.Open()
cnMain.Open()
Dim cmd As New System.Data.OleDb.OleDbCommand("SELECT * INTO [MSAccess;DATABASE=" & My.Settings.MainDB & ";].[tblCertHeader] FROM tblCertHeader WHERE ID = " & iCertNo, cnLocal)
cmd.ExecuteNonQuery()
cnMain.Close()
cnLocal.Close()
I'm thinking it's either do it the way listed above. Or to open two connections get one row from the local and then insert it into cnMain - but again not sure how to do this without listing all the fields... Can I just simply insert the row ?
it appears you are running from one MS Access database to another, so the connect string is much simpler:
SELECT * INTO [;DATABASE=C:\MainDB.mdb;].[Header] FROM [Header] WHERE ID=9
BTW It may not be possible to update a database in C:\, if that is a real path.
EDIT I tested with this:
''Dim sSQL As String
''Dim iCertMainNo As Integer
Dim cnLocal As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Docs\dbFrom.mdb;")
''Dim cnMain As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & My.Settings.MainDB & ";")
cnLocal.Open()
''cnMain.Open()
Dim cmd As New System.Data.OleDb.OleDbCommand("SELECT * INTO [;DATABASE=C:\Docs\DBTo.mdb;].[Header] FROM Header WHERE ID = 2", cnLocal)
cmd.ExecuteNonQuery()
''cnMain.Close()
cnLocal.Close()
And it worked fine for me. I commented out iCertMainNo because you did not use it. Your string included only iCertNo, for which i used the actual value for test purposes. I did not see any reason for two connections.
Related
I need to start a query to retrieve data from Access database using VBA which I want to use a variable number as a parameter. Is it possible?
like the:
field name: NMT field type (number)
table name: Orders
and the code is like the following:
Dim Con As New ADODB.Connection
Dim RS As New ADODB.Recordset
Dim X as Integer
X = me.textbox1.value
Con.Open "Provider= Microsoft.ACE.OLEDB.12.0;Data Source=" & U.Database01 & "\DB.accdb;Persist Security Info=False"
Rs.Open "select * from Orders where nmt = '" + X + "'", Con, adOpenDynamic, adLockPessimistic
Whenever I run this query, I get a run-time error '13' type mismatch.
Any suggestions ?
Multiple Issues
Type-mismatch in WHERE clause:
Your query (i.e. the WHERE clause) tries to compare a Number-column from database with a String-value (e.g. WHERE numberField = '123'). This will result in a runtime error Type mismatch (Error 13). See also similar question.
Unsafe to use + to concatenate Strings
When building the query you tried to concatenate the query-template with the number-parameter by a plus-sign. This works only when operating on numbers. See related question
Solution
remove single-quotes: you should compare the Number-column NMT with a number literal (e.g. WHERE nmt = 123)
use & to concatenate strings. This will also convert numbers to strings. Besides I explicitly used CStr function below.
Dim Con As New ADODB.Connection
Dim RS As New ADODB.Recordset
Dim strSQL As String
Dim nmtNumber as Integer ' you named it x before
nmtNumber = me.textbox1.value
strSQL = "SELECT * FROM Orders WHERE nmt = " & CStr(nmtNumber) ' removed single-quotes and used ampersand to concatenate with converted string
Con.Open "Provider= Microsoft.ACE.OLEDB.12.0;Data Source=" & U.Database01 & "\DB.accdb;Persist Security Info=False"
RS.Open strSQL, Con, adOpenDynamic, adLockPessimistic
Further improvement
I already extracted the SQL string (building) into a separate variable strSQL above.
Better would be to use predefined/prepared and parameterized queries:
QueryDef (DAO) where you can set the parameters (type-safe). See this question.
Command (ADODB) where you can set parameters (type-safe). See this question.
See also
What is ‘Run-time error ‘13’: Type mismatch’? And How Do You Fix It?
VBA Type Mismatch Error
For i As Integer = 0 To dgclassinfo.Rows.Count - 1
LRN = dgclassinfo.Rows(i).Cells(2).Value.ToString
Lname = dgclassinfo.Rows(i).Cells(3).Value.ToString
Fname = dgclassinfo.Rows(i).Cells(4).Value.ToString
Mname = dgclassinfo.Rows(i).Cells(5).Value.ToString
comm.CommandText = "insert into g7(LRN,Lname,Fname,Mname ) values('" & LRN & "','" & Lname & "','" & Fname & "','" & Mname & "')"
comm.ExecuteNonQuery()
Next
I used to code above to import my data. Using dgv. My data is databound. for additional info. When I import the file it reads the value of the excel and displays in the dgv in which i insert the data using the for loop above. I think I need to use mydr.hasrows but I have no idea on how to do this using for loop. How can I check for duplicate records every row? LRN is my pk.
Any help will be appreciated.
To check if record exists, u can actually check the database's specific column to see if the column has any rows containing the same record u are trying to insert..TO do this,first u need to check the database for duplicates and then insert new data if no duplicates exist.A full example might look like this :
Dim cmd as new SqlCommand("Select * from TABLENAME([column names-remove brackets if required])values(#value1)",con)
cmd.parametres.AddWithValue("#value1",Firstname.Text)
Dim dr as new SqlDataReader=cmd.Executereader
If dr.hasRows Then 'This checks if any duplicates exist
Msgbox("Duplicates Found")
Else
Dim cmd as new SqlCommand("Inserting data query here",con)
cmd.parametres.Add("#value1",SqlDbtype.Varchar).value=Firstame.Text
cmd.ExecuteNonQuery
Here i've assumed u r using Sql Server, make necessary changes to the code
Why is this code not working? Sorry for the generic question....
I am tasked with generating reports with reference information that needs to be drawn from an access database and an excel spreadsheet.
Basically in my role I'm responsible for providing service to people who live in a community; the record of all the people I provide service for is contained in an access database. There's reference information; address, name, situation, and other information needed for regular reports to funders or the board of directors.
I also provide service to local businesses; this information is contained within a spreadsheet, and not a database. The information could be put into a relational database, with the two related together; but there is resistance at the organization for significant changes to the system, nor is there really the knowledge of how to do this.
So I'm trying to move forward with a spreadsheet - if I provide service to person A or organization B, that this spreadsheet will check both the access database, and the excel spreadsheet to see whether that person or organization is entered; if it is, it should populate a table with that information, and assign it a unique code.
The unique code is determined on the basis of the database; whether or not the person or organization has been entered into the database before.
The spreadsheet I am working at the base with is this:
The bottom table I am looking to be a 'lookup' table. Its name is Lookup. The code I want to run with it looks like this (but obv not is this):
Sub getUserID()
Dim myTable As ListObject
Set myTable = Sheets("Client Codes").ListObjects("Lookup")
If myTable.ListRows.Count >= 1 Then
myTable.DataBodyRange.Delete
End If
With Sheets("Client Codes").ListObjects("Lookup").Add(SourceType:=0, Source:=Array(Array("ODBC;DSN=MS Access Database;DBQ=C:\database\here\test.accdb;DefaultDir=F:\Housing;DriverId=25;FIL=MS Access;MaxBufferSize=2048;PageTimeo"), Array("ut=5;")), Destination:=myTable.Range(Cells(1, 1)))
.CommandText = Array("SELECT Clients.ID, Clients.LastName, Clients.FirstName " & Chr(13) & "" & Chr(10) & "FROM `C:\database\here\test.accdb`.Clients Clients" & Chr(13) & "" & Chr(10) & "WHERE (Clients.LastName='" & Range("b1").End(xlDown) & "') AND (Clients.FirstName='" & Range("c1").End(xlDown) & "')")
End With
With Sheets("Client Codes").ListObjects("Lookup").Add(SourceType:=0, Source:=Array(Array("ODBC;DSN=Excel Files;DBQ=C:\spreadsheet\here\text.xlsx;DefaultDir=c:\spreadsheet;DriverId=1046;MaxBufferSize=2"), Array("048;PageTimeout=5;")), Destination:=myTable.Range(Cells(1, 1)))
.CommandText = Array("SELECT `Businesses$`.Operation" & Chr(13) & "" & Chr(10) & "FROM `C:\spreadsheet\here\test.xlsx`.`Businesses$` `Businesses$`" & Chr(13) & "" & Chr(10) & "WHERE (`Businesses$`.Operation='" & Range("b1").End(xlDown) & "')")
End With
End Sub
The hope is to be able to query the database on the basis of either a persons first and last name, or to query the spreadsheet on the basis of organization name; and if there is a value that is found, to add some information to the table 'Lookup'. If nothing is found, then I will know its a new entry, and enter in the information as such.
For reference, the database has 3 fields (ID, LastName, FirstName); and the spreadsheet has 1 column (Operation).
Really the confusion is focused here:
How to 'add' the information based on a query to the listobject to a pre-existing table
How to do this both with an access database and an Excel spreadsheet
Any suggestions on other ways how this can be done would be appreciated; pull information from multiple data sources into one table so that it can be validated in that table.
EDIT: If I did this through Access or another database program, I would do an INNERJOIN on two tables; one of people, the other of businesses. I'm looking to keep excel though - I find it to be more user friendly.
EDIT: Code based on Ian's response....generates the following error message:
'run time error -2147467259, could not find installable ISAM'
Research on the internet seems to indicate the following:
1) People have gotten this error before
2) There might not be a proper DLL installed - not certain this is the case, because I'm trying to access access from excel, and it doesn't seem like there is a DLL for access here: https://support.microsoft.com/en-us/kb/209805
3) There might be issue of how the connection string is framed. The data source might need to be in quotes, the JET OLEDB needs to be used not ACE, the connection string needs to be extended to include 'extended properties' here: Error: "Could Not Find Installable ISAM"
The last one is obviously the biggest target (and has the most error about it).
Option Explicit
Sub getUserID()
Dim cmd As New ADODB.Command
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strConn As String
Dim strSQL As String
Dim firstName As String
Dim lastName As String
firstName = "John"
lastName = "Smith"
strConn = "Provider = Microsoft.ACE.OLEDB.12.0;'DataSource=F:\Housing\bpTest.accdb'"
conn.Open strConn
strSQL = "SELECT * FROM Table Where FirstName = '" & firstName & "' AND LastName = '" & lastName & "';"
'& ... ' or You could put your InnerJoin SQL here
rs.Open strSQL, conn, adOpenDynamic, adLockOptimistic
If rs.EOF Then 'If the returned RecordSet is empty
MsgBox ("No record found")
Else
MsgBox (rs.Index)
End If
end sub
You will most like want to use ActiveX Data Objects to accomplish this. This will let you to pull data from the access database and also update the records in the access database from Excel.
Here is the Microsoft reference material: https://msdn.microsoft.com/en-us/library/ms677497(v=vs.85).aspx
And some sample code:
Dim cmd As New adodb.Command
Dim conn As New adodb.Connection
Dim rs As New adodb.Recordset
Dim strConn As String
strConn = "Provider = Microsoft.ACE.OLEDB.12.0;" _
& "Data Source=C:\AccessDatabse.accdb"
conn.Open strConn
strSQL = "SELECT * FROM Table Where FristName =" & strName & ... ' or You could put your InnerJoin SQL here
rs.Open strSQL, conn, adOpenDynamic, adLockOptimistic
If rs.EOF then 'If the returned RecordSet is empty
'...there is no match in database
Else
'the rs object will hold the ID you are looking for
End If
you can add a new records to the Access Database with:
myFieldList = Array("ID", "FirstName", "LastName")
myValues = Array(IDValue, FirstNameValue, LastNameValue)
rs.AddNew myFieldList, myValues
I am coding in vb on visual studio 2012 and I need to create a query that pulls table data into a datagriddview. I have a textbox for user input and a combobox to set what the column name. Sort of like, "SELECT * FROM TITLES WHERE COMBOBOX LIKE TEXTBOX". I apologize if this question is old ground for you but I looked everywhere and couldn't find what I was looking for. Also I am a total newb so please speak slowly and in small words. Thanks in advance for your help.
You need to modify your SQL to be:
"SELECT * FROM TITLES WHERE " & ComboBox1.Text & " LIKE '%" & TextBox1.Text & "%'"
Deja Vu's answer should be ok. You may take it a step further, and try using a parameter instead of building the sql string directly from users' direct input, thus avoiding SQL Injection (which is a security risk):
Dim Sql As String = "SELECT * FROM MYTABLE WHERE " & ComboBox1.Text & " LIKE '%?%' "
Dim p As New OleDb.OleDbParameter : p.Value = Textbox1.text
Dim OleDBCommand As New OleDb.OleDbCommand(Sql, Connection)
OleDBCommand.Parameters.Add(p)
Dim da As New OleDb.OleDbDataAdapter(OleDBCommand)
Dim DT As New DataTable
da.Fill(DT)
(Note: I'm assuming this is an Application and users must choose an item from the combobox, and they cannot change the content of the combobox.)
I've run into a bit of trouble guys. After days of labouring, debugging and researching, im on the 3rd to last line and im stuck. This isnt the full code, but the relevant parts.
Dim dbProvider As String
Dim dbSource As String
Dim con As New OleDb.OleDbConnection
Dim ds As New DataSet
Dim MaxRows As Integer
Dim sql As String
Dim TableName As String
TableName = TbTableName.Text
Dim da As New OleDb.OleDbDataAdapter("SELECT * FROM [" & TableName & "]", con)
Dim cb As New OleDb.OleDbCommandBuilder(da)
Dim dsNewRow As DataRow
Dim dsNewColoumn As DataColumn
dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;"
dbSource = "Data Source = E:\A2 Computing\Project\PasswordDatabase.mdb"
con.ConnectionString = dbProvider & dbSource
con.Open()
Dim TableCreate As New OleDb.OleDbCommand("CREATE TABLE [" & TableName & "](" & "ID INTEGER NOT NULL" & ")", con)
Dim NewColoumn As New OleDb.OleDbCommand("ALTER TABLE [" & TableName & "] ADD " & X & " VARCHAR(60)", con)
TableCreate.ExecuteNonQuery()
da.Fill(ds, "NewTable")
MaxRows = ds.Tables("NewTable").Rows.Count
ds.Tables("NewTable").PrimaryKey = New DataColumn() {ds.Tables("NewTable").Columns("CustID")}
X = 0
Do
X = X + 1
dsNewColoumn = ds.Tables("NewTable").Columns.Add
ds.Tables("NewTable").Columns.Add(X)
dsNewRow = ds.Tables("NewTable").NewRow()
ds.Tables("NewTable").Rows.Add(dsNewRow)
Loop Until X = 30
da.InsertCommand = cb.GetInsertCommand()
da.UpdateCommand = cb.GetUpdateCommand()
da.Update(ds, "NewTable")
End Sub
The problem im having is at this line here
da.UpdateCommand = cb.GetUpdateCommand()
The error is
Dynamic SQL generation for the UpdateCommand is not supported against a SelectCommand that does not return any key column information.
I understand this means my table doesnt have a primary key, but i have set one. Any help would be greatly appreciated! =)
You need the key column in the DB.
The command builder doesn't use the key you set in the datacolumn in the dataset.
In fact, if you look at the code, CB create command used by DA, but CB has no reference to your ds.Tables("NewTable").PrimaryKey, so CB will never be able to take your PrimaryKey in consideration.
So, you need to set a primary key in the DB.
Anyway, why do you have a Database table without a primary key?
Update (after reading the first 9 comments)
You define the Table columns in the TableCreate SQL command, when you execute this command it will create the table AND the column IN the database file.
A table can be empty (no rows) but MUST have at least a column.
You CAN'T use the dataset/datatable abstraction/object to add real column to the real table in the database, it doesent works this way (see point 1)
It give you the error "SSSS.ID' cannot contain a Null" because in the SQL CREATE command you are creating a table with a column called ID that is NOT NULL (see the "ID INTEGER NOT NULL" part of the command) so if you add a row to this table, the column ID MUST contain a value that is not null.
your loop is adding a column at the datatable for each iteration, it doesn't work this way, you cant do that. And if you do, you are doing it wrong.
The column "CustID" you are adding at the datatable exist only in the datatable (the "in-memory" abstraction of the real table) it will never exist in the DB (unless you add it to the CREATE TABLE command)
In my opinion you need to:
Study a good book on RDBMS and SQL (to learn the basics of how a DB works, tables, relations, key, columns, datatype, SQL, null value....)
Read some good article/book on how dataset/datatable/connection interact with a real DB