Google Answers Logo
View Question
 
Q: Visual Basic or C++ Source Code - Convert ASCII text file to SQL entry ( Answered 5 out of 5 stars,   0 Comments )
Question  
Subject: Visual Basic or C++ Source Code - Convert ASCII text file to SQL entry
Category: Computers > Programming
Asked by: mrsneaky-ga
List Price: $50.00
Posted: 26 May 2003 20:11 PDT
Expires: 25 Jun 2003 20:11 PDT
Question ID: 209182
Prerequisites: 
Source code works with MS Visual Studio newer than 6.0 and MS SQL
(2000 or newer)

Deliverables:
Source Code
Example of text in Test File
Spec for test file (field lenghts)
TESTED SQL script to build table with appropriate fields in MS-SQL 


*****
I would like the source code for a program written in Visual Basic
(preferred) or C++ that takes a fixed link text file with 10 data
components and inserts the data into a SQL table.  The data and table
are to be created by the responder (more details below on some
specifications.)  The table will also have some management fields –
Status (3 digit numeric field). A field that inserts when (time date)
the data was processed according to system clock.  Use incrementing
ident field as unique identifier.

3 fields numeric (1 with commas, integer, and 1 field that has 3
positions after a decimal) - 1 field character (any character) - 1
field date - 1 field date-time - 1 field currency that will be
translated from the text file – format - XXXXXXX.XX – 3 fields
alphanumeric with some basic error checking (valid characters or value
of a number and space or character padding would be a good example.)
(it is up to the responder the level and extent would be a good
example)

You will need to create the sample file specification and the format
of the test file (please use the examples above from above - use some
creativity on data file to show examples).  I would like the sample
files to have "different" lengths for the data types.

The program should be able to be compiled and executed without
modification in Visual Studio (please provide version it was tested in
6.0 pr newer).

The program should scan multiple lines of test file (if the data exist
-
Each file that the program scans will have at least 1 line of data).

The program should scan at a hard coded interval of every 20 seconds a
hard coded directory (C:\TEST1) for a specific file type (*.tst). 
Move and rename the converted files into another directory
(C:TEST1\DONE\*.dne).  Move the files then rename in 2 lines of code.

Please comment source code to show flow and logic (tip available for
extraordinary source code comment documentation).

Next project will be to take data from the same database and create
the files based on a status field (like 20).  Additional $50 tip
available if you want to do both programs.

Request for Question Clarification by mathtalk-ga on 26 May 2003 21:32 PDT
Hi, mrsneaky-ga:

I can write this in VB6 or in VB.Net (either the original or new 2003
flavor).

You can see an example of a formless VB6 program that interacts with
SQL Server 2000 here:

http://answers.google.com/answers/main?cmd=threadview&id=201716

Which version of VB do you prefer?  How do you want to authenticate in
SQL Server: Windows authentication or "mixed mode" (SQL Server login)?
 How do you want to launch the program?  (I can suggest answers to
these questions, if you like.)

How fast do you need it?

regards, mathtalk

Clarification of Question by mrsneaky-ga on 27 May 2003 09:03 PDT
Thank you for your response.  No particular hurry (I'm traveling for a
couple of days.

I'll leave authentication up to you (easier is better) - SQL
authentication using SA is fine.

Newer the version the better (but not required.)

I prefer the program to run as "desktop" application.  A button to
start and stop the program would be nice.  Any debugging windows
during operation would be nice but not required.

If you need further clarification it will be this evening (after 7ish
CDT) before I can get back.)

THANKS!
Mr. Sneaky

Request for Question Clarification by mathtalk-ga on 29 May 2003 08:46 PDT
Hi,

I've got a question about the arrival rates of these files.  You ask
for the program to check every 20 seconds.  I'm wondering if the
expected arrival rate is much slower than that.  If not we might want
to give some thought to the priority of processing files when there is
more than one.  I.e. should they be processed oldest first, or
according to some other criterion.

Also, I wonder if you want the same timestamp to apply to all records
in one file.  That would provide a convenient way of grouping those
records once they've been inserted into the database.

Finally, I'm wondering if a file contains some bad, some good records,
how do you want to handle it?  Is this an all or nothing situation, or
do you want as many good records posted as possible?  The "renaming"
of processed files and copying them to a different directory serves a
"logging" purpose for the processed files, but presumably we'd want to
put files that are not completely processed into a different folder
(or at least use a different renaming convention).

regards, mathtalk-ga

Clarification of Question by mrsneaky-ga on 29 May 2003 09:23 PDT
the files will arive "sporatically" with a different extension and be
"renamed" to the "searched" extension, therefore open files will not
be an issue.  But a group of lets say 20 files can definitly show up.

It would be "nice" if the program would process them oldest first (but
not required).  The time stamp grouping sounds great...  I'm more
interested in the code syntax of reading the system time and inserting
it into the field.

I think a basic total length check would be great (since it should be
fixed length).  And the failed files have the extension *.bad.  (or
put in a different folder)

EXCELLENT thinking of some of the exceptions.  Thanks in advance!

Obviously, the begininnings of a "interface" program, so I don't
expect every consideration to be taken, but your efforts will be
rewarded!

Phase 3: if you are up to the challenge and shouldn't take too long is
to make the "hard coded directories" registry entries so they can be
changed.  In addition the looping cycle and extension types.  Don't
make everything registry driven as I want to use your examples and
learn how to do it myself.  i think those would be a good start.

I prefer HKEY Local machine/Software/testprogram (or something like
that).
  Would an additional $30 be worth the modification.  Otherwise not a
big deal.


THANKS AGAIN!

Clarification of Question by mrsneaky-ga on 29 May 2003 09:24 PDT
FYI the files that are placed and renamed in the directory will be
renamed by an external program.

Request for Question Clarification by mathtalk-ga on 29 May 2003 09:38 PDT
Ummm... you mean that after our program renames and moves them,
another program will rename them again?  Or that the program we're
writing should just move them and not worry about the renaming?

-- mathtalk

Clarification of Question by mrsneaky-ga on 29 May 2003 10:31 PDT
See what happens when I type fast...  The files will be put into the
scanning directory from an "external" program with the extension *.pre
(but the possibility exist that these files will be "open" as they are
written.  Once this external program finishes this program will rename
the files *.pre to *.tst (the file this program is scanning for.  So
your program does not have to deal with "open" files.

After you process the *.tst files I would like them to placed into
"processed" directory (C:\test1\done) then after you place the *.tst
files in the directory I would like them to renamed to *.dne.  So I'm
guessing the syntax would move the file then a second line of code to
"rename" the file.  (I'm sure you can probably do it in 1 step, but I
prefer 2 so I can see the syntax.

I hope this clears it up to the "work flow".

you mentioned putting the "error" files in a "third" directory and I
that would be a GREAT enhancement.

Phase 4 (another $50 bonus - if you should choose to accept): 
Logging!  A logging directory should be created and each time a
"batch" of files are being processed a log file with "process"
information be "logged" in *.log file  I would like the file name to
be a date time stamp.

Basic logging information such as login to the database SQL insert and
update statements etc.  (This way when I modify the program and it
doesn't work I can easily troubleshoot it, without the source code) 
The log would also include any SQL "responses".

So as I see it $50 for the question as it stands.  $50 for the
turnaround program (SQL to text) $30 for registry modification and $50
for logging files.

So we'll make it a total of $200.  Is that fair?  Again you may choose
and pick any or all of the pieces.

Thanks again!
Mr. Sneaky

Request for Question Clarification by mathtalk-ga on 29 May 2003 12:47 PDT
Okay, thanks for the prompt clarification.  The pricing for additional
pieces is agreeable.

regards, mathtalk-ga

Clarification of Question by mrsneaky-ga on 29 May 2003 13:47 PDT
I can't tell you how much I appreciate your efforts...  I want to get
into programming and other systems for my small company, but going to
a class just seemed like a waste considering I have a full time job. 
I rather just start with a working model and then build the details as
I go along.  I was hoping to ask a aquestion to someone who had "most"
of the parts and could stick it together.

I'll ask you a question next after this question about parsing a comma
(or some other predetermined character settable with a registry
setting) delimited variable length file into the same database table
so don't delete it.

Thanks again,
MrSneaky

Request for Question Clarification by mathtalk-ga on 07 Jun 2003 07:25 PDT
Hi, mrsneaky-ga:

I've been working away on the VB.Net project, but I thought you'd like
to have some bits to review on the database side.

Your specification requires a table with three fields for "management"
and ten fields taken from the text import file.  Based on the
discussion of the fields above, I wrote and tested this SQL Server
2000 script to create a "CarSales" table with the required fields and
to test it with a sample INSERT and SELECT:

DROP TABLE  CarSales
go

CREATE TABLE  CarSales (
    carsid  int IDENTITY(1,1) PRIMARY KEY,
    timedt  datetime NOT NULL,
    status  smallint NOT NULL CHECK (status BETWEEN 1 and 999),
    ncomma  decimal NOT NULL,
    nwhole  int NOT NULL,
    nthous  decimal(38,3) NOT NULL,
    csngle  char(1) NOT NULL,
    dtonly  datetime NOT NULL,
    dttime  datetime NOT NULL,
    nmoney  money NOT NULL,
    strxox  char(3) NOT NULL,
    strnnx  char(3) NOT NULL,
    strabc  varchar(3) NOT NULL
)
go

INSERT into CarSales 
  (timedt, status, ncomma, nwhole, nthous, csngle, 
   dtonly, dttime, nmoney, strxox, strnnx, strabc)
VALUES 
  (GETDATE(), 1, 1234567890, 500, 3.142, 'P',
   '4/1/2000','04/01/1998 12:15:00.012 AM',
   1234567.89, 'XOX', '99X', 'AB')
go

SELECT * from CarSales

By the way, I'm leaning toward using Windows authentication for
simplicity.  A desktop application (with a single button flipping
between Start and Stop) will pick up the user credentials from the
logon session in which it executes, so there would be no need to "hard
code" an SA logon within the application.

regards, mathtalk-ga
Answer  
Subject: Re: Visual Basic or C++ Source Code - Convert ASCII text file to SQL entry
Answered By: mathtalk-ga on 16 Jun 2003 13:12 PDT
Rated:5 out of 5 stars
 
Hi, mrsneaky-ga:

I've proceeded to performing the requirements based on the 
intial table design given above.  The coding done assumes
a locally hosted SQL Server 2000 database called "mrsneaky"
in which the CarSales table has already been created using
the script given above.

Next let's describe the "file specification".  I made some
small changes to your filenaming conventions.  Input files
should have the extension .XNC (for transactions ?), and 
the extension gets changed to .DNE (for success, per your
requirements) or .XNR (for errors) after moving these to
the .\DONE subdirectory.  Also I chose C:\MyXNC as the main
file directory (rather than C:\TEST1, as you requested).

> > > > > > File Specification BEGINS > > > > > > > > >

Layout of "80 byte" fixed length file records:

FIELD     LENGTH  COLUMNS   Notes:
ncomma      10      1-10      Numeric, but may contain commas
nwhole       5     11-15      Integer numeric (no commas)
nthous       9     16-24      Three places after decimal point
                              XXXXX.XXX   (right justified)
csngle       1        25      Any character
dtonly      10     26-35      A date in format MM/DD/YYYY
dttime      26     36-61      Datetime MM/DD/YYYY HH:MM:SS.mmm
                              with optional AM or PM appended
nmoney      10     62-71      Two places after decimal point
                              XXXXXXX.XX  (right justified)
strxox       3     72-74      Three letters with middle vowel
strnnx       3     75-77      Two digits and a letter or space
strabc       3     78-80      One to three captial letters in
                              ascending order (left justified)

An ASCII character set is assumed.  Note that records may be
terminated by carriage returns, line feeds, or both, or in 
the case of the last record by the end of file.

All fields are required to be nonempty, i.e. at least one
nonspace character (except csngle, which will be treated as
a space character if that is provided) but padded with space
character or optionally zeros in the case of numeric values,
as necessary.

It is recommended that numeric fields be right justified and
character fields left justified; however apart from specific
requirements noted above the implementation allows for small
amounts of flexibility.

< < < < < < END OF File Specification < < < < < < < < <

A sample file is a little hard to present here because the 
Google Answers text here wraps after 70 columns, so bear in 
mind that the following needs to be rejoined into a single 
line (and also that a space occupies the 80th column):

> > > > > C:\MyXNC\New Text Document.xnc BEGINS > > > > >
12,345,678  500    3.142P04/01/200004/01/1998 12:15:00.012 AM1234567.89XOX99XAB 
< < < < < END OF C:\MyXNC\New Text Document.xnc < < < < <

Note that my file spec allows for the lines to exceed 80
columns and places no restrictions (except ASCII encoding)
on what additional columns may contain.  In my experience
it is good to plan for this type of "extensibility" and
does not cost much.  One drawback is that it can make it
harder to check for errors caused by lines running together,
but my purpose here is very much weighted toward coding the
database functions in a readable and "solid" manner without
getting overly bogged down in defensive coding issues.

I will give you a link to a place on the Web where you can
download the zipped up project files.  However let me give
the VB.Net code below, after a few words about how it was
constructed.

I created a "solution" called MrSneaky that currently has
only a single project Importxt.

I chose a "Standard EXE" Windows executable from among the
VB.Net project types.  On the intial form (Form1) I placed
only a minimum number of items (controls) using the IDE:

- a button (Button1)

- a label (Label1)

Apart from changing the Form propert Text to "Import Text"
(so that appears in the form's title bar) and using the IDE
to create the shell code for Button1_Click, all this code
was edited in manually to the basic program outline.  The
process started by adding certain variable declarations at
the top of the program (just above the computer generated
code that says "Windows Form Designer Generated Code".  In
fact these declaration modify the basic "Class" definition
of Form1, to incorporate these extra "global" (instance)
variables:

    Dim bProcess As Boolean
    Dim tmrFndTx As System.Timers.Timer
    Dim dirMyXNC As System.IO.DirectoryInfo
    Dim cnSneaky As System.Data.SqlClient.SqlConnection
    Dim cmSneaky As System.Data.SqlClient.SqlCommand

Declaring those variables only makes a placeholder for each
of them.  The contents get initialized at the point in the
computer generated subroutine New() for application class
Form1, under the comment that says:

'Add any initialization after the InitializeComponent() call

A quick explanation of these variables:

- bProcess is tied to the "state" of the "command" button
  and reflects whether the process is running or not.

- tmrFndTx is a timer that fires (when enabled) after 20 secs.
  The enabled state coincides with bProcess, and the firing
  event is handled by a routine that looks for the .XNC files,
  then resets the enabled state.

- dirMyXNC is a .Net runtime object used to check for the
  existence of the C:\MyXNC directory (and create it if it
  does not exist) and some related tasks

- cnSneaky is an ADO.Net database "connection" object, and
  cmSneaky is a "command" object derived from it.  Together
  they are used to communicate with the database and insert
  records into the table CarSales.

The code currently reads like this (including all computer
generated lines).  NOTE:  The Google Answers textbox doesn't
preserve leading tabs on lines, so the appearance below will
necessarily be only a rough approximation of what you'd see
in the IDE once the project files are downloaded.  I've tried
to avoid any unintended line wrapping, but I apologize in
advance where this occurs, e.g. within the computer generated
code:

> > > > > > > > > Form1.vb BEGINS > > > > > > > > > > >

Public Class Form1
    Inherits System.Windows.Forms.Form

    Dim bProcess As Boolean
    Dim tmrFndTx As System.Timers.Timer
    Dim dirMyXNC As System.IO.DirectoryInfo
    Dim cnSneaky As System.Data.SqlClient.SqlConnection
    Dim cmSneaky As System.Data.SqlClient.SqlCommand

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call
        bProcess = False
        tmrFndTx = New System.Timers.Timer(20000)
        AddHandler tmrFndTx.Elapsed, AddressOf OnTimedFind
        tmrFndTx.AutoReset = False
        tmrFndTx.Enabled = False

        If System.IO.Directory.Exists("C:\MyXNC") Then
            dirMyXNC = New System.IO.DirectoryInfo("C:\MyXNC")
        Else
            dirMyXNC = System.IO.Directory.CreateDirectory("C:\MyXNC")
        End If

        If Not System.IO.Directory.Exists("C:\MyXNC\Done") Then
            dirMyXNC.CreateSubdirectory("Done")
        End If

        cnSneaky = New System.Data.SqlClient.SqlConnection
        cnSneaky.ConnectionString = "Data Source=localhost;" _
            + "Integrated Security=SSPI;Initial Catalog=mrsneaky"
        cmSneaky = cnSneaky.CreateCommand()

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents Label1 As System.Windows.Forms.Label
    <System.Diagnostics.DebuggerStepThrough()> Private _
    	Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.Label1 = New System.Windows.Forms.Label
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Font = New System.Drawing.Font("Microsoft Sans Serif", _
        	9.75!, System.Drawing.FontStyle.Bold, _
        	System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Button1.Location = New System.Drawing.Point(72, 64)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(128, 40)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Start"
        '
        'Label1
        '
        Me.Label1.Font = New System.Drawing.Font("Microsoft Sans Serif", _
        	10.0!, System.Drawing.FontStyle.Bold, _
        	System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Label1.Location = New System.Drawing.Point(72, 24)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(128, 23)
        Me.Label1.TabIndex = 1
        Me.Label1.Text = "Import Text to SQL"
        Me.Label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 165)
        Me.Controls.Add(Me.Label1)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Import Text"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private Sub OnTimedFind(ByVal source As Object, _
    	ByVal e As System.Timers.ElapsedEventArgs)
        ' unless boolean bProcess is True, simply return
        If Not Me.bProcess Then Return

        ' make Button1 inactive during this processing
        Me.Button1.Enabled = False

        ' search for files *.xnc in directory C:\MyXNC
        Dim fiArr As System.IO.FileInfo() = _ 
        	dirMyXNC.GetFiles("*.xnc")
        ' TODO: sort the entries in fiArr by creation datetime
        Dim fi As System.IO.FileInfo
        For Each fi In fiArr
            Dim result As Boolean = ProcessFileXNC(fi)
            ' move file to .\Done
            Dim pathDoneXNC As String = dirMyXNC.FullName _ 
            	+ "\Done\" + fi.Name
            fi.MoveTo(pathDoneXNC)
            Dim len As Integer = pathDoneXNC.Length
            Dim pathDone As String = _
            	pathDoneXNC.Substring(0, len - 3)
            If result Then
                ' rename to *.dne
                System.IO.File.Move(pathDoneXNC, pathDone + "dne")
            Else
                ' rename to *.xnr
                System.IO.File.Move(pathDoneXNC, pathDone + "xnr")
            End If
        Next fi

        ' restart the Timer object
        Me.tmrFndTx.Start()

        ' reenable the "command button"
        Me.Button1.Enabled = True

    End Sub

    Private Function ProcessFileXNC(ByVal fi As System.IO.FileInfo) _
    	As Boolean
        ' extract the transaction data from file, validate and post

        Dim dtXNC As System.DateTime
        cmSneaky.CommandText = "select GETDATE()"
        Try
            cnSneaky.Open()
            dtXNC = cmSneaky.ExecuteScalar()
        Catch ex As Exception
            System.Windows.Forms.MessageBox.Show( _
            	"command failed to execute: " + ex.Message)
        Finally
            cnSneaky.Close()
        End Try

        Dim millisc As Integer = dtXNC.Millisecond
        Dim strMill As String = millisc.ToString("D3")
        Dim strDtTm As String = dtXNC.ToString("s") + "." + strMill
        ' System.Windows.Forms.MessageBox.Show(strDtTm)

        Dim srText As System.IO.StreamReader = fi.OpenText
        Dim strLine, strVals As String
        Dim result As Boolean = True

        strLine = srText.ReadLine()
        Do
            ' parse the line of text into insertable values
            strVals = parseCarSales(strDtTm, strLine)
            If strVals.Length > 0 Then
                cmSneaky.CommandText = strVals

                Try
                    cnSneaky.Open()
                    cmSneaky.ExecuteNonQuery()
                Catch ex As Exception
                    System.Windows.Forms.MessageBox.Show( _
                    	"insert failed to execute: " + ex.Message)
                    Return False
                Finally
                    cnSneaky.Close()
                End Try

            Else
                result = False
            End If

            strLine = srText.ReadLine()
        Loop Until strLine Is Nothing

        srText.Close()
        Return result
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, _ 
    	ByVal e As System.EventArgs) Handles Button1.Click
        bProcess = Not bProcess
        tmrFndTx.Enabled = bProcess

        If bProcess Then
            Try
                cnSneaky.Open()
                ' starting: change button label to Stop from Start
                Button1.Text = "Stop"
            Catch ex As Exception
                ' TODO: figure out better strategy for handling
                System.Windows.Forms.MessageBox.Show( _
                	"problem opening connection:" + ex.Message)
                bProcess = Not bProcess
                tmrFndTx.Enabled = bProcess
            Finally
                cnSneaky.Close()
            End Try

        Else
            ' stopping: change button label to Start from Stop
            Button1.Text = "Start"
        End If
    End Sub

    Private Function parseCarSales(ByVal strDtTm As String, _ 
    	ByVal strLine As String) As String
        ' build SQL syntax for the insert statement
        Dim strProlog As String = "INSERT into CarSales " _
            + "(timedt, status, ncomma, nwhole, nthous, csngle, " _
            + " dtonly, dttime, nmoney, strxox, strnnx, strabc) " _
            + "VALUES ('" + strDtTm + "', 1, "
        Dim strNcomma, strNwhole, strNthous, strCsngle As String
        Dim strDtonly, strDttime, strNmoney As String
        Dim strXOX, strNNX, strABC As String

        ' return an empty string if any input data is invalid
        Dim bValid As Boolean
        ' allow for longer lines than strictly required by feed
        bValid = (strLine.Length >= 80)

        ' extract, validate and format ncomma field
        If bValid Then
            strNcomma = strLine.Substring(0, 10)
            ' trim white space from beginning and end
            strNcomma = strNcomma.Trim()
            ' remove commas: replace them with empty strings
            strNcomma = strNcomma.Replace(",", "")
            ' validate by checking IsNumeric
            bValid = IsNumeric(strNcomma)
        End If

        ' extract, validate and format nwhole field
        If bValid Then
            strNwhole = strLine.Substring(10, 5)
            ' trim white space from beginning and end
            strNwhole = strNwhole.Trim()
            ' validate with regular expression
            bValid = System.Text.RegularExpressions.Regex.IsMatch( _
            	strNwhole, "^[+-]?[0-9]+$")
        End If

        ' extract, validate and format nthous field
        If bValid Then
            strNthous = strLine.Substring(15, 9)
            ' trim white space from beginning (right justification)
            strNthous = strNthous.TrimStart()
            ' validate with regular expression
            bValid = System.Text.RegularExpressions.Regex.IsMatch( _
            	strNthous, "^[+-]?[0-9]*\.[0-9]{3}$")
        End If

        ' extract, validate and format csngle field
        If bValid Then
            ' format character in single quotes for SQL
            strCsngle = "'" + strLine.Substring(24, 1) + "'"
        End If

        ' extract, validate and format dtonly field
        If bValid Then
            strDtonly = strLine.Substring(25, 10)
            ' validate by checking IsDate and if it's okay...
            bValid = IsDate(strDtonly)
            ' ... then check Time parts hour & minute are zero
            If bValid Then
                bValid = (DatePart("h", strDtonly) = 0) _ 
                	And (DatePart("n", strDtonly) = 0)
            End If
            ' format date in single quotes for SQL
            strDtonly = "'" + strDtonly + "'"
        End If

        ' extract, validate and format dttime field
        If bValid Then
            strDttime = strLine.Substring(35, 26)
            ' validate by checking IsDate
            bValid = IsDate(strDttime)
            ' formate date in single quotes for SQL
            strDttime = "'" + strDttime + "'"
        End If

        ' extract, validate and format nmoney field
        If bValid Then
            strNmoney = strLine.Substring(61, 10)
            ' trim white space from beginning (right justification)
            strNmoney = strNmoney.TrimStart()
            ' validate with regular expression
            bValid = System.Text.RegularExpressions.Regex.IsMatch( _
            	strNmoney, "^[+-]?[0-9]*\.[0-9]{2}$")
        End If

        ' extract, validate and format strxox field
        If bValid Then
            strXOX = strLine.Substring(71, 3)
            ' validate with regular expression
            bValid = System.Text.RegularExpressions.Regex.IsMatch( _
            	strXOX, "[a-zA-Z][aeiouAEIOU][a-zA-Z]")
            ' format string with single quotes for SQL
            strXOX = "'" + strXOX + "'"
        End If

        ' extract, validate and format strnnx field
        If bValid Then
            strNNX = strLine.Substring(74, 3)
            ' validate with regular expression
            bValid = System.Text.RegularExpressions.Regex.IsMatch( _
            	strNNX, "[0-9][0-9][a-zA-Z]")
            ' format string with single quotes for SQL
            strNNX = "'" + strNNX + "'"
        End If

        ' extract, validate and format strabc field
        If bValid Then
            strABC = strLine.Substring(77, 3)
            ' trim white space from end (assume left justification)
            strABC = strABC.TrimEnd()
            ' validate with regular expression and if it's okay...
            bValid = System.Text.RegularExpressions.Regex.IsMatch( _ 
            	strABC, "[A-Z]+")
            ' then check the ascending order of characters
            If bValid And strABC.Length > 1 Then
                For I As Integer = 1 To strABC.Length - 1
                    bValid = bValid And (strABC.Chars(I - 1) _
                    	<= strABC.Chars(I))
                Next I
            End If
            ' format string with single quotes for SQL
            strABC = "'" + strABC + "'"
        End If

        If bValid Then
            Return strProlog + strNcomma + ", " _
                + strNwhole + ", " + strNthous + ", " _
                + strCsngle + ", " + strDtonly + ", " _
                + strDttime + ", " + strNmoney + ", " _
                + strXOX + ", " + strNNX + ", " + strABC + ")"
        Else
            Return ""
        End If

    End Function
End Class
< < < < < < < END OF Form1.vb < < < < < < < < < < < < <

When I get those project files loaded up on the Web, I'll
post some additional comments about the programming techniques
used, esp. for the validation of fields which I think is of
particular interest to you.

regards, mathtalk-ga

Clarification of Answer by mathtalk-ga on 17 Jun 2003 07:29 PDT
Hi, Charlie:

The required project files can be downloaded here:

[MrSneaky Solution & Importxt Project]
http://www.lucidmatrix.com/upload/mrsneaky.zip

When unzipping/extracting the files, use the option to preserve
directory structure.  I've been doing my development in My
Documents\Visual Studios Projects, but you'll probably have a
different setup.  In any case the files in the zip archive above will
unpack into a "MrSneaky" subdirectory in whatever directory you wish
(e.g. you could extract to C:\, in which case it will create the
MrSneaky directory there).

I suggest navigating into that folder with Windows Explorer and
double-clicking on MrSneaky.sln, the "solution" file.  This should
launch VS.Net 2003 for you, assuming it's installed.

Clarification of Answer by mathtalk-ga on 17 Jun 2003 07:39 PDT
Ooops, I accidentally hit the post clarification button too soon!

The link should actually be this (note missing 's' in uploads before):

[MrSneaky Solution & Importxt Project] 
http://www.lucidmatrix.com/uploads/mrsneaky.zip 

When you launch VS.Net 2003 as above, the IDE will look kind of empty,
but the Solution Explorer "tree" control should be visible.  Double
click on the Form1.vb node in the tree, the usual "form" display
should appear.  You can then "View > Code" from the menu in the usual
way, and of course you should try "Build > Build Importxt" from the
menu as well.  Let me know if there are any problems.

Thanks for the kind words of encourgement, though I'm frankly not even
a demiurge in the Google panoply!  I thought it would be best to do
the extract of records (into a text file) as a separate question, as
some discussion of the requirements will be useful on that.  As I
recall you wanted the extract query to key off of the status code, and
currently I'm just setting of those fields to 1 on import.

regards, mathtalk-ga


regards, mathtalk-ga

Request for Answer Clarification by mrsneaky-ga on 04 Jul 2003 18:20 PDT
I had ankle surgery this week, and I'm off on vacation to recoup for a
couple weeks.  I haven't forgotten, just to tired to look at all this
right this second.

But I'll list a follow-up 3rd week in July.

Thanks,
Charlie

Clarification of Answer by mathtalk-ga on 05 Jul 2003 08:38 PDT
Hi, Charlie:

Sorry to hear about the surgery!  I hope you get a good result, and
that the vacation is truly restful.

regards, mathtalk
mrsneaky-ga rated this answer:5 out of 5 stars and gave an additional tip of: $100.00
I tried to rate this and it failed...  Try #2 - GREAT, I'm traveling
this week and don't have good opportunity to test it, but looks great
on the surface!  I'll post the follow up (to pay the additional $50)
and to add a character delimited source file!  you are the GOOGLE
GOD!!!  :)

I didn't realize the $100.00 tip limit when we "negotiated".  ;)

Thanks,
Charlie

Comments  
There are no comments at this time.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy