Given the paths of each database, the names of each tables, the fields for comparison, and the path for the final output file, each application will work return a list of species found in the main table that are not in the reference table to the screen and to the output file. I'm going to post each program, a link to download it.
Here are my inputs that I am using:
Reference Database: Personal_FSVEG.mdb
Reference Table: fs_nris_fsveg_NRV_R5_SPECIES_XWALK
Reference Field: NRIS_SPEC
InputDatase: mnfplus07_1inv.mdb
Input Table: FSVEG_TXPT_V
Input Field: SPEC
Output Files
Missing_Species_VB.txt
Missing_Species_Python_adodb.txt
Missing_Species_Python_Win32com.txt
Accessing the database in VB.Net through ADO.Net
It did not take me long to write this but, because it so easy I gave it a GUI.Here is the code
Imports System.IO
Public Class frmMainForm
Dim whatfile, var, whatpath, pathvar As String
Dim U As Integer
Dim DS As DataSet
Dim projectfile As String
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles frmMain.Click
Dim var As Object, i As Integer, ConnectionString As String, q As String
Dim adapter As New OleDb.OleDbDataAdapter
Me.OpenFileDialog1.InitialDirectory = "C:\"
Me.OpenFileDialog1.Filter = "Access Database (*.mdb)|*.MDB"
Me.OpenFileDialog1.ShowDialog()
whatfile = Me.OpenFileDialog1.FileName
If whatfile <> vbNullString Then
var = Split(whatfile, "\", -1)
U = 0
For Each q In var
U = U + 1
Next q
For i = 0 To U - 2
whatpath = whatpath & var(i) & "\"
Next i
End If
Me.txtinputfile.Text = whatfile
pathvar = whatpath
DS = New Data.DataSet
DS.Clear()
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Me.txtinputfile.Text
Dim conn As OleDb.OleDbConnection = New OleDb.OleDbConnection(ConnectionString)
conn.Open()
Dim dt As Data.DataTable = conn.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, _
New Object() {Nothing, Nothing, Nothing, "TABLE"})
'List the table name from each row in the schema table.
For i = 0 To dt.Rows.Count - 1
Me.cboCompareTable.Items.Add(dt.Rows(i)!TABLE_NAME.ToString)
Next i
'Explicitly close - don't wait on garbage collection.
conn.Close()
End Sub
Private Sub cmdRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRun.Click
Dim adapterTXPT As New OleDb.OleDbDataAdapter
Dim ConnectionString2 As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Me.txtinputfile.Text
Dim adapter As New OleDb.OleDbDataAdapter
Dim ConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Me.txtReferenceFile.Text
adapterTXPT = New OleDb.OleDbDataAdapter("SELECT DISTINCT " & Me.cboCompaeField.Text & " FROM " & Me.cboCompareTable.Text, ConnectionString2)
' Code to modify data in DataSet here
Try
adapterTXPT.MissingSchemaAction = MissingSchemaAction.AddWithKey
adapterTXPT.Fill(DS, "CompareTable")
Catch
MsgBox("Error is: " & Err.Number & " " & Err.Description)
End Try
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Me.txtReferenceFile.Text
adapter = New OleDb.OleDbDataAdapter("SELECT DISTINCT " & Me.cboReferenceField.Text & " FROM " & Me.cboReferenceTable.Text, ConnectionString)
' Code to modify data in DataSet here
Try
adapterTXPT.MissingSchemaAction = MissingSchemaAction.AddWithKey
adapterTXPT.Fill(DS, "CompareTable")
Catch
MsgBox("Error is: " & Err.Number & " " & Err.Description)
End Try
Try
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
adapter.Fill(DS, "ReferenceTable")
Catch
MsgBox("Error is: " & Err.Number & " " & Err.Description)
End Try
If File.Exists(projectfile) Then
File.Delete(projectfile)
End If
Dim writenow As Boolean = True
Dim MyFile As IO.StreamWriter
MyFile = New System.IO.StreamWriter(projectfile, True) ' True for appending
MyFile.WriteLine("Missing Species found in the TXPT")
Dim dtTXPT As DataTable
dtTXPT = DS.Tables("CompareTable")
Dim dtREF As DataTable
dtREF = DS.Tables("ReferenceTable")
Dim dr As DataRow, SPEC As String, drref As DataRow
writenow = True
For Each dr In dtTXPT.Rows
SPEC = dr(Me.cboCompaeField.Text)
For Each drref In dtREF.Rows
If SPEC = drref(Me.cboReferenceField.Text) Then
writenow = False
Exit For
End If
Next
If writenow Then
lstTXPT.Items.Add(SPEC)
MyFile.WriteLine(SPEC) ' Write text to file
End If
writenow = True
Next
MyFile.Close() ' Close file
MsgBox("Done")
End Sub
Private Sub cmdQuit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdQuit.Click
End
End Sub
Private Sub cmdSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSave.Click
Me.FolderBrowserDialog1.Reset()
Me.FolderBrowserDialog1.ShowDialog()
pathvar = Me.FolderBrowserDialog1.SelectedPath.ToString
Dim projectname As String = InputBox("Type the name you want to give the report file:", "Choose name for Report")
projectfile = pathvar & "\" & projectname
Me.txtoutput.Text = projectfile
End Sub
Private Sub frmMainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub cmdBrowseRefernceFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBrowseRefernceFile.Click
Dim var As Object, i As Integer, ConnectionString As String, q As String
Dim adapter As New OleDb.OleDbDataAdapter
Dim adapterTXPT As New OleDb.OleDbDataAdapter
Dim adapterVXPT As New OleDb.OleDbDataAdapter
Me.OpenFileDialog1.InitialDirectory = "C:\"
Me.OpenFileDialog1.Filter = "Access Database (*.mdb)|*.MDB"
Me.OpenFileDialog1.ShowDialog()
whatfile = Me.OpenFileDialog1.FileName
If whatfile <> vbNullString Then
var = Split(whatfile, "\", -1)
U = 0
For Each q In var
U = U + 1
Next q
For i = 0 To U - 2
whatpath = whatpath & var(i) & "\"
Next i
End If
Me.txtReferenceFile.Text = whatfile
pathvar = whatpath
DS = New Data.DataSet
DS.Clear()
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Me.txtReferenceFile.Text
Dim conn As OleDb.OleDbConnection = New OleDb.OleDbConnection(ConnectionString)
conn.Open()
Dim dt As Data.DataTable = conn.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, _
New Object() {Nothing, Nothing, Nothing, "TABLE"})
'List the table name from each row in the schema table.
For i = 0 To dt.Rows.Count - 1
Me.cboReferenceTable.Items.Add(dt.Rows(i)!TABLE_NAME.ToString)
Next i
'Explicitly close - don't wait on garbage collection.
conn.Close()
End Sub
Private Sub cboCompareTable_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboCompareTable.SelectedValueChanged
Dim Connectionstring As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Me.txtinputfile.Text
Dim adapter As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter("SELECT * FROM " & Me.cboCompareTable.Text, Connectionstring)
Try
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
adapter.Fill(DS, Me.cboCompareTable.Text)
Catch
MsgBox("Error is: " & Err.Number & " " & Err.Description)
End Try
Dim fld As DataColumn, dr As DataRow
dr = DS.Tables(Me.cboCompareTable.Text).Rows(0)
For Each fld In dr.Table.Columns
Me.cboCompaeField.Items.Add(fld.ColumnName)
Next
End Sub
Private Sub cboReferenceTable_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboReferenceTable.SelectedValueChanged
Dim Connectionstring As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Me.txtReferenceFile.Text
Dim adapter As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter("SELECT * FROM " & Me.cboReferenceTable.Text, Connectionstring)
Try
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
adapter.Fill(DS, Me.cboReferenceTable.Text)
Catch
MsgBox("Error is: " & Err.Number & " " & Err.Description)
End Try
Dim fld As DataColumn, dr As DataRow
dr = DS.Tables(Me.cboReferenceTable.Text).Rows(0)
For Each fld In dr.Table.Columns
Me.cboReferenceField.Items.Add(fld.ColumnName)
Next
End Sub
Private Sub cmdClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdClear.Click
With Me
.txtinputfile.Text = ""
.txtoutput.Text = ""
.txtReferenceFile.Text = ""
Dim t As Integer, i As Integer
i = .lstTXPT.Items.Count
For t = 1 To i
.lstTXPT.Items.RemoveAt(0)
Next
i = .cboCompareTable.Items.Count
For t = 1 To i
.cboCompareTable.Items.RemoveAt(0)
Next
i = .cboReferenceField.Items.Count
For t = 1 To i
.cboReferenceField.Items.RemoveAt(0)
Next
i = .cboReferenceTable.Items.Count
For t = 1 To i
.cboReferenceTable.Items.RemoveAt(0)
Next
i = .cboCompaeField.Items.Count
For t = 1 To i
.cboCompaeField.Items.RemoveAt(0)
Next
End With
End Sub
End Class
Here is the VB.Net version in action
I like doing this kind of work in VB because GUIs are so easy and fast to put together.
Accessing the database in Python
Fortunately, there was plenty of information about how to achieve the same effect in Python. I found two ways of doing it. Neither way offers a GUI but instead a user interactively enters inputs using commandline.Accessing the database in Python through ADOdb/mxODBC
In scouring the Internet, I found the following library for Python. ADOdb depends on the mxODBC library. The information for how to get them can be found here and there. As I stated in a previous post, the mxODBC library is not free but you can get a 30-day license in which to to test. It is also important to remember that you must install these libraries to get the following script to work.Here is the Python code using the ADOdb/mxODBC libraries
'''
Created on Oct 13, 2009
@author: marcusmcelhaney
'''
#This script will be designed to compare a given inventory file versus a species reference table
#This is to test ODBC connection to Access Databases
#Results will be printed out on screen and in a file.
#Uses Python 2.5
#Used the technique from http://phplens.com/lens/adodb/adodb-py-docs.htm#install
#Start connections to Access database
# ODBC for Access database containing the Reference table
import adodb
import os.path
lstTXPT = []
#get the location of the reference file
reffile = input('Enter the file path and name for reference file: ')
inputfile2 = os.path.split(reffile)
reffile = inputfile2[0] + "\\" + inputfile2[1]
#reffile = "C:/Temp/Personal_FSVEG.mdb"
#get Reference SQL Statement
reffield = input("Enter field to get Records from the reference table: ")
#reffield="NRIS_SPEC"
#Get Reference table
refTable = input("Enter Reference Table: ")
#refTable = "fs_nris_fsveg_NRV_R5_SPECIES_XWALK"
conn0 = adodb.NewADOConnection('access') # mxodbc required
dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=" + reffile + ";"
conn0.Connect(dsn)
cursor = conn0.Execute('select distinct ' + reffield + " from " + refTable)
#get the location of the inventory file
inputfile = input('Enter the file path and name for inventory: ')
inputfile2 = os.path.split(inputfile)
inputfile = inputfile2[0] + "\\" + inputfile2[1]
#inputfile = inputfile.replace("\", "/",5)
#Get compare field
comparefield = input("Enter the field to compare in the desired table: ")
#comparefield = "SPEC"
#Get compare table
CompareTable = input("Enter the name of the table you are comparing: ")
#CompareTable = "FSVEG_TXPT_V"
out_file = open("c:/Temp/Missing_Species_Python_adodb.txt", "w")
#Make connection string for inventory file
conn2 = adodb.NewADOConnection('access') # mxodbc required
dsn2 = "Driver={Microsoft Access Driver (*.mdb)};Dbq=" + inputfile + ";"
conn2.Connect(dsn2)
cursorTXPT = conn2.Execute('select distinct ' + comparefield + ' from ' + CompareTable)
print "Getting list of comparefield not in Compare Table"
writenow = True
cursorTXPT.MoveNext()
while not cursorTXPT.EOF:
DesiredSPEC = cursorTXPT.fields[0]
while not cursor.EOF:
if DesiredSPEC == cursor.fields[0]:
writenow = False
cursor = conn0.Execute('select distinct ' + reffield + " from " + refTable)
break
cursor.MoveNext()
if writenow:
lstTXPT.append(DesiredSPEC)
out_file.write(DesiredSPEC)
cursor = conn0.Execute('select distinct ' + reffield + " from " + refTable)
writenow = True
cursorTXPT.MoveNext()
cursorTXPT.Close()
cursor.Close()
conn2.Close()
conn0.Close()
print "Missing Species from the TXPT"
for species in lstTXPT:
print species
out_file.close()
print "Done"
Accessing the database in Python through Win32com
Here is the other method I found for connecting a python script into an Access database. I think this will be my method of choice because it's library is free and the syntax and use closely mirrors that of ADO classic which I am very familiar with. Here is the code:'''
Created on Oct 15, 2009
@author: marcusmcelhaney
'''
#This script will be designed to compare a given inventory file versus a species reference table
#This is to test ODBC connection to Access Databases
#Results will be printed out on screen and in a file.
#Uses Python 2.5
#Used the technique Win32com
#Start connections to Access database
# ODBC for Access database containing the Reference table
import win32com.client
import os.path
lstTXPT = []
#get the location of the reference file
reffile = input('Enter the file path and name for reference file: ')
inputfile2 = os.path.split(reffile)
reffile = inputfile2[0] + "\\" + inputfile2[1]
#reffile = "C:/Temp/Personal_FSVEG.mdb"
#get Reference SQL Statement
reffield = input("Enter field to get Records from the reference table: ")
#reffield="NRIS_SPEC"
#Get Reference table
refTable = input("Enter Reference Table: ")
#refTable = "fs_nris_fsveg_NRV_R5_SPECIES_XWALK"
connexion = win32com.client.gencache.EnsureDispatch('ADODB.Connection')
dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=" + reffile + ";"
connexion.Open(dsn)
AD_OPEN_KEYSET = 1
AD_LOCK_OPTIMISTIC = 3
rs = win32com.client.Dispatch(r'ADODB.Recordset')
rs.CursorLocation = 3
offset = 1
rs.Open('select distinct ' + reffield + " from " + refTable, connexion, AD_OPEN_KEYSET, AD_LOCK_OPTIMISTIC)
#get the location of the inventory file
inputfile = input('Enter the file path and name for inventory: ')
inputfile2 = os.path.split(inputfile)
inputfile = inputfile2[0] + "\\" + inputfile2[1]
#inputfile = inputfile.replace("\", "/",5)
#Get compare field
#comparefield = input("Enter the field to compare in the desired table: )
comparefield = "SPEC"
#Get compare table
CompareTable = input("Enter the name of the table you are comparing: ")
#CompareTable = "FSVEG_TXPT_V"
out_file = open("c:/Temp/Missing_Species_Python_win32com.txt", "w")
#Make connection string for inventory file
connexion2 = win32com.client.gencache.EnsureDispatch('ADODB.Connection')
dsn2 = "Driver={Microsoft Access Driver (*.mdb)};Dbq=" + inputfile + ";"
connexion2.Open(dsn2)
AD_OPEN_KEYSET = 1
AD_LOCK_OPTIMISTIC = 3
rsTXPT = win32com.client.Dispatch(r'ADODB.Recordset')
rsTXPT.CursorLocation = 3
offset = 1
rsTXPT.Open('select distinct ' + comparefield + ' from ' + CompareTable, connexion2, AD_OPEN_KEYSET, AD_LOCK_OPTIMISTIC)
print "Getting list of comparefield not in Compare Table"
writenow = True
# expand the recordset as list of tuples
while not rsTXPT.EOF:
rsTXPT.MoveNext
DesiredSPEC = rsTXPT.Fields.Item(comparefield).Value
rs.MoveNext
while not rs.EOF:
if DesiredSPEC == rs.Fields.Item(reffield).Value:
writenow = False
rs.Close()
rs.Open('select distinct ' + reffield + " from " + refTable, connexion, AD_OPEN_KEYSET, AD_LOCK_OPTIMISTIC)
break
rs.MoveNext()
if writenow:
lstTXPT.append(DesiredSPEC)
out_file.write(DesiredSPEC)
rs.Close()
rs.Open('select distinct ' + reffield + " from " + refTable, connexion, AD_OPEN_KEYSET, AD_LOCK_OPTIMISTIC)
writenow = True
rsTXPT.MoveNext()
rsTXPT.Close()
rs.Close()
connexion2.Close()
connexion.Close()
print "Missing Species from the TXPT"
for species in lstTXPT:
print species
out_file.close()
print "Done"
You can down load the source code below
| Name | Purpose | Link | |||
|---|---|---|---|---|---|
| VB.Net version | Software installer |
| |||
| VB.Net Source code | Project files |
| |||
| Python ADOdb Source code | Project files |
| |||
| Python Win32com Source code | Project files |
| |||
| Personal_FSVEG.mdb | Reference database |
| |||
| Comparing Inventory | Test database |
|

No comments:
Post a Comment