I have two databases in IDEA: Database A & Database B. I want to compare the Quantity field from these two files and both Databases have a key of RecordID. I would like to create an IDEAScript Macro to perform this process rather than do it manually. Can someone outline how to create this macro?
You can use the CompareDB function in IDEAScript. Example Code:
Set db1 = Client.OpenDatabase("DatabaseA.IMD")
Set DoCompare = db1.CompareDB
DoCompare.AddMatchKey "RecordID", "RecordID", "A"
DoCompare.PerformTask "Output.imd", "", "QUANTITY", "QUANTITY", "DatabaseB.imd"
Set DoCompare = Nothing
Set db1 = Nothing
Client.CloseDatabase "DatabaseA.IMD"
Client.OpenDatabase "Output.imd"
Related
Wow, my first stack question despite using the answers for years. Very exciting.
I'm fairly new to VBA and Excel and entirely new to Access, full disclosure. So Im trying to create a core database of lab reports, and I have a form for entering the information about a new report which adds info about the report to a master table of all reports, including assigning it a unique label. After entering the info, I then have a button which allows the user to select the Excel .csv file accompanying the report and imports it into the DB as a new table. It returns a success or error message. And it works! (And the code came from somewhere on here)
The problem is I'd like to then add a field to the new table that adds the label assigned to the new report to all records so it can be referenced by queries through the use of that label. I'd also like to add an index field to the new table if possible as it doesn't seem like importing the .csv as a table creates an index. I figure I'll make another sub that gets passed the new report name as a name for the new field (which will also be the value of the field through all records) and the table to append that to.
How do I pass this sub the newly imported table if I just imported it? I need this all to work from the button as it will mostly be my manager using this form/button to import new files, and they won't be able to just manually go into the tables as they are created and add fields (yes, I know that's the obvious solution, but trust me...this must be a button)
Heres the code I'm using (yes, I know lots of it could be done differently but it works!)
Public Function ImportDocument() As String
On Error GoTo ErrProc
Const msoFileDIalogFilePicker As Long = 3
Dim fd As Object
Set fd = Application.FileDialog(msoFileDIalogFilePicker)
With fd
.InitialFileName = "Data Folder"
.Title = "Enthalpy EDD Import"
With .Filters
.Clear
.Add "Excel documents", "*.xlsx; *.csv", 1
End With
.ButtonName = " Import Selected "
.AllowMultiSelect = False 'Manual naming currently requires one file at a time be imported
'If aborted, the Function will return the default value of Aborted
If .Show = 0 Then GoTo Leave 'fb.show returns 0 if 'cancel' is pressed
End With
Dim selectedItem As Variant
Dim NewTableName As String
NewTableName = InputBox(Prompt:="Enter the Report Name", _
Title:="Report Name")
For Each selectedItem In fd.SelectedItems 'could later be adapted for multiple imports
DoCmd.TransferText acImportDelim, , NewTableName, selectedItem, True 'Imports csv file selected, true is 'has headers'
Next selectedItem
'Return Success
ImportDocument = "Success"
'Append report label and index
AppendReportLabelField(NewTableName, #What to put here as the table to append to?)
'error handling
Leave:
Set fd = Nothing
On Error GoTo 0
Exit Function
ErrProc:
MsgBox Err.Description, vbCritical
ImportDocument = "Failure" 'Return Failure if error
Resume Leave
End Function
The AppendReportLabelField would get passed the name (and value) of the field and the name of the (newly imported) table. How do I pass it the table? NewTableName is just a string currently. If I can pass the new sub the table I'm sure the rest will be simple.
Thanks in advance for the help!
Consider storing all user input data in a single master table with all possible fields and use a temp, staging table (a replica of master) to migrate CSV table to this master table. During the staging, you can update the table with needed fields.
SQL (save as stored queries)
(parameterized update query)
PARAMETERS [ParamReportNameField] TEXT;
UPDATE temptable
SET ReportNameField = [ParamReportNameField]
(explicitly reference all columns)
INSERT INTO mastertable (Col1, Col2, Col3, ...)
SELECT Col1, Col2, Col3
FROM temptable
VBA
...
' PROCESS EACH CSV IN SUBSEQUENT SUBROUTINE
For Each selectedItem In fd.SelectedItems
Call upload_process(selectedItem, report_name)
Next selectedItem
Sub upload_process(csv_file, report_name)
' CLEAN OUT TEMP TABLE
CurrentDb.Execute "DELETE FROM myTempStagingTable"
' IMPORT CSV INTO TEMP TABLE
DoCmd.TransferText acImportDelim, , "myTempStagingTable", csv_file, True
' RUN UPDATES ON TEMP TABLE
With CurrentDb.QueryDefs("myParameterizedUpdateQuery")
.Parameters("ParamReportNameField").Value = report_name
.Execute dbFailOnError
End With
' RUNS APPEND QUERY (TEMP -> MASTER)
CurrentDb.Execute "myAppendQuery"
End Sub
If CSV uploads vary widely in data structure, then incorporate an Excel cleaning step to standardize all inputs. Alternatively, force users to use a standardized template. Staging can be used to validate uploads. Databases should not be a repository of many, dissimilar tables but part of a relational model in a pre-designed setup. Running open-ended processes like creating new tables by users on the fly can cause maintenance issues.
Is there any way to read all the data from excel and put it in the datatable or any other container so that i can filter the data based on the conditions required. As shown in attached image i want to get the CuValue of a Partnumber whose status is Success and i want the latest record based on the Calculation date(Latest calculation date). In the below example i want the CuValue 11292 as it is the latest record with status Success..lue.
Thanks in advance
Your question seems very broad, but you're right to ask because there are many different possibilities and pitfalls.
As you don't provide any sample code, i assume you are looking for a strategy, so here is it.
In short: create a database, a table and a stored procedure. Copy the
data you need in this table, and then query the table to get the
result.
You may use ADO for this task. If it is not available on your machine you can download and install the MDAC redistributable from the Microsoft web site.
The advantage vs. OLE Automation is that you doesn't need to install Excel on the target machine where the import shall be executed, so you can execute the import also server-side.
With ADO installed, you will need to create two Connection objects, a Recordset object to read the data from the Excel file and a Command object to execute a stored procedure which will do the INSERT or the UPDATE of the subset of the source fields in the destination table.
Following is a guideline which you should expand and adjust, if you find it useful for your task:
Option Explicit
Dim PartNo as String, CuValue as Long, Status as String, CalcDate as Date
' objects you need:
Dim srcConn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim rs As New ADODB.Recordset
Dim dstConn As New ADODB.Connection
' Example connection with your destination database
dstConn.Open *your connection string*
'Example connection with Excel - HDR is discussed below
srcConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Scripts\Test.xls;" & _
"Extended Properties=""Excel 8.0; HDR=NO;"";"
rs.Open "SELECT * FROM [Sheet1$]", _
srcConn, adOpenForwardOnly, adLockReadOnly, adCmdText
' Import
Do Until rs.EOF
PartNo = rs.Fields.Item(0);
CuValue = rs.Fields.Item(1);
CalcDate = rs.Fields.Item(6);
Status = rs.Fields.Item(7);
If Status = "Success" Then
'NumSuccess = NumSuccess + 1
' copy data to your database
' using a stored procedure
cmd.CommandText = "InsertWithDateCheck"
cmd.CommandType = adCmdStoredProc
cmd(1) = PartNo
cmd(2) = CuValue
cmd(3) = CalcDate
cmd.ActiveConnection = dstConn
cmd.Execute
Else
'NumFail = NumFail + 1
End If
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
srcConn.Close
Set srcConn = Nothing
dstConn.Close
Set dstConn = Nothing
'
By using a stored procedure to check the data and execute the insert or update in your new table, you will be able to read from Excel in fast forward-only mode and write a copy of the data with the minimum of time loss, delegating to the database engine half the work.
You see, the stored procedure will receive three values. Inside the stored procedure you should insert or update this values. Primary key of the table shall be PartNo. Check the Calculation Date and, if more recent, update CuValue.
By googling on the net you will find enough samples to write such a stored procedure.
After your table is populated, just use another recordset to get the data and whatever tool you need to display the values.
Pitfalls reading from Excel:
The provider of your Excel file shall agree to remove the first two or three rows, otherwise you will have some more work for the creation of a fictitious recordset, because the intelligent datatype recognition of Excel may fail.
As you know, Excel cells are not constrained to the same data type per-column as in almost all databases.
If you maintain the field names, use HDR=YES, without all the first three rows, use HDR=NO.
Always keep a log of the "Success" and "Fail" number of records read
in your program, then compare these values with the original overall
number of rows in Excel.
Feel free to ask for more details, anyway i think this should be enough for you to start.
There are lots ways you can do this.
1. You can create an access DB table and import by saving your sheet as can file first, into the access table. Then you can write queries.
2. You can create a sql DB and a table, write some code to import the sheet into that table.
3. You can Write some code in VBA and accomplish that task if your data is not very big.
4. You can write c# code to access the sheet using excel.application and office objects, create a data table and query that data table
Depends on what skills you want to employ to accomplish your task.
I would like to be able to split a string of text that has been entered into a textbox on a MS Access form and store the split strings as separate records under the same field. This is the code I have so far, but I keep running into problems at every corner. I'm fairly new to this, but have been learning quickly. Any help is appreciated.
Here is what I'd like to accomplish: If I enter the following text into a text box ("this is a sentence") and click submit. I would like each other the words to be stored as individual records under a common field. Seems simple, but it's causing quite a few headaches.
Private Sub Submit_Click()
Dim SetDBConnection As ADODB.Connection
Set SetDBConnection = CurrentProject.Connection
Dim strInsertRecord As String
Dim strNewPhrase As String
Dim strStorePhrase As String
strNewPhrase = textPhrase
strStorePhrase = Split(NewPhrase)
strInsertRecord = "INSERT INTO [FieldSplice] (words) VALUES (" & strStorePhrase & ")"
SetDBConnection.Execute strInsertRecord
textPhrase.Value = Null
End Sub
I'm a little unclear on why you have the ADODB connection... is this connecting to an external database? If so, that makes sense, but then you are missing some code to get the insert to work properly.
If this is just an internal (native) Access table, then I don't think you need any of that. Here is a simple example of how you would take a string, split it into words (based on a space) and then insert those into your table:
Dim textPhrase As String
Dim words() As String
Dim i As Integer
textPhrase = "This is a test"
words = Split(textPhrase, " ")
sql = "parameters P1 text; INSERT INTO [FieldSplice] (words) VALUES ([P1])"
Set query = CurrentDb.CreateQueryDef("FsInsert", sql)
For i = LBound(words) To UBound(words)
query.Parameters("P1").Value = words(i)
query.Execute
Next i
CurrentDb.QueryDefs.Delete ("FsInsert")
One other note of interest -- you don't need to declare the insert each time. You can set a parameter, assign values to the parameter and execute the insert command multiple times. This is included in my example above.
Your code was trying to say:
insert into [table] (field) values ("value1", "value2", "value3")
Which you can't do. That has to be done as three inserts, unless your database supports array inserts (Oracle, for example).
The multiple fields only works like this:
insert into [table] (field1, field2) values ("value1", "value2")
Where each value corresponds to a column in the table.
I'm trying to change values of an excel workbook using Update but something is wrong i.e. y want to get the value from table B and put it in table a
my code is this, can you help me?
UPDATE [Data$]
SET A.[D ArtN] = B.[D ArtC]
FROM [Datos$] as A
INNER JOIN [Productos$] as B
ON A.[Art] = B.[ArtC]
UPDATE [Data$]
SET [Data$].[D ArtN] = [Productos$].[D ArtC]
WHERE [Data$].[Art] = [Productos$].[ArtC]
Is the correct format of an update statement. I'm not sure that this is the correct SQL syntax, as you did not specify if what you were using in Excel.
http://www.w3schools.com/sql/sql_update.asp
I have an excel dokument (tab delimitted). Every time before i can insert the excel in my program, i need to map the clients column names to the ones in my app.
So before i begin developing a mapping tool - it would be better if such already existed. But, i don't know i didn't find it.
This tool would actually read an excel or txt file, allow me to name all the names of the new columns on the right and drag and drop (for example).
Maybe this tool has an xml or something where i can define my custom columns, and then it would show op on the right side.
I hope you know what i mean and that someone also had the need for this.
Thanks
info update
I wanted to mention a few things as an update to my question if it's not to late: I have about 50 headers/columns (example: First Name, Middle Name, Street1, Street2,..). So what i always need do every time a client gives me his excel file (contacts backup) is manually copy data for each of his column to the one on my side. And the problem is, every client has different column names, and also some of the columns of the client can go to multiple columns on my side.
So i think, if i can't find a solution, i would make a c++/qt app, which takes an excell and lets me to assign (dragdrop,etc..) every column of his side to on or more columns of my side.
I haven't done any vb programming, so if you can be a bit more detailed about how to aproach the solution i vb that would be great.
Firs part of answer: You can achieve it with a simple vbscript. Copy this code in a vbs extension text file and double click.
Dim oCN As Connection
Dim fs As Scripting.FileSystemObject
Set oCN = New Connection
Set fs = New Scripting.FileSystemObject
sCSVFileName = "C:\Temp\Test1.csv"
sSourceSql = "SELECT field1 as f1, field2 as f2, ... FROM " &
fs.GetFileName(sCSVFileName )
sDestinationTable = "yourAppTable"
With oCN
.Provider = "Microsoft.Jet.OLEDB.4.0"
.Properties("Extended Properties").Value =
"TEXT;HDR=YES;FMT=TabDelimited;MAXSCANROWS=0"
.Open fs.GetFile(sCSVFileName).ParentFolder
End With
sSql = "INSERT INTO [ODBC;DRIVER={SQL Server};Server=" &
ServerName & ";Database=" & DBName & _
IIf(IntegratedSecurity, ";Trusted_Connection=Yes;", _
";UID=" & UID & ";PWD=" & PWD & ";") & _
"]." & sDestinationTable & " " & sSourceSql
oCN.Execute sSql, , adExecuteNoRecords
More info at microsoft social forums
Also, you can parametrize mapping (source and destination tables and mapping fields) with a external xml file.
Second part of answer: You ask if somebody else have this needed and if this is a good idea. Well, this is a very good proposal. And for this reason they are some solutions with this functionality.
First of all, this kind of technology is named ETL. Extract - Transform - Load.
Each database has its own tool
SQL Server Import and Export Wizard
Oracle data pump and loader
etc.
Also exists specific technologies:
SSIS from microsoft.
IBM WebSphere DataStage
etc.
All this tools have mapping columns capabilities.
i use a generic mapping mechanism for that, configured by a couple arrays where you put the names used in your app (aDsNames) with these in your source, the csv file in your case (aDbNames)
I walk the fields in the source, check if the getDbName(name) is in aDsNames and if so write the value in the insertstring to the database.
You can do this both ways, usually my app requests a field to the databasemodule on the server, this module translates to the databasename and does the select.
Hope this is helpfull..
Cheers
select case store
case "store1Midoc"
aDbNames = array("id" , "beheerder", "datumlijst", "rnr13" , "datvan", "dattot", "opmerking", "status" , "waarde", "kode" , "type")
aDsNames = array("id" , "persnr ", "datum ", "rnr13" , "datvan", "dattot", "opmerking", "status" , "waarde", "kode" , "type")
aTypes = array("number", "string", "date" , "string", "date" , "date" , "string" , "number", "number", "string", "string")
case .....
end select
Function getDbName(dsName)
Dim a
getDbName = "undefined"
If instr(join(aDsNames,","),dsName) Then
For a = 0 to UBound(aDbNames)
If aDsNames(a) = dsName Then
getDbName = aDbNames(a)
End If
Next
End If
End Function