This will be a quick summary for those who do not want to know the detailed implementation.
The reason for this codes existance is to create a way to space delimit each character of the txt file that
is to be submitted. It needed some very specific parameters. EAMS BULK Filing Specifications
Given the high level of specificity needed for this, it was a perfect place for a program to automate
away a few hours of work.
The basic execution is, it takes these three sheets: AccountingDoc, EmployeeData, and CompanyData. The
AccountingDoc sheet is the input sheet where each character of the cell data in EmployeeData and CompanyData
is place.
So as a quick example:
I hope this shows what it is that it does. You will notice that the characters from cell
A2 have been spread out into cells B2 - J2 in the final format.
There are a lot of other caviots, but that is the basic idea.
The Breakdown:
PopulatBulkFile()
It starts off very simply describing the high level process of execution. I brought in the three sheets,
then populated the data from the data sheets into the AccountingData sheet and save the sheet as a new workbook.
Done!
Hardly... I will start with the population of the T and F records as they are much simpler.
PopulateFRec()
I'm going to start with the F record. It is the shortest so I will be able to lay down some basics of the
other two functions work.
The variables defined here are defined through each of the functions. First there is the LowerBound[]
and UpperBound[] arrays. These will store the values of the range of column indeces that the current
cells characters will be seperated into.
These values are defined by the EAMS Bulk filing specifications.
Next The FRow variable is defined. This is the the row number that the "F" data will be put into.
FindRecord()
To find the "F" row I pass in the sheet I want to search and the string to search for.
This function works by looking in Column A and finding the first instance where the cell value equals the
FindRec string that was passed to it. I then returns the row number it was found in.
Here the CompanyData sheet is searched using the string that is one row up, in the first
cell of the current range. So the first search term will be "Total Number of Employees", and the row that
string is found in within the CompanyData sheet will be returned.
Next the value in column 2 is collected. Then one of the important formatting characteristics come into play.
In this case the cell value must be populated in the right most cell first. So in the for loop
I get the length of the string and each character is pull out from right to left and put into the cell
UpperBound(i) - j.
Of course the Left(Right(DataValue, j + 1), 1) could be replaced with a simpler
MID(DataValue, Len(DataValue) - j, 1).
This process is then done for each of the LowerBound and UpperBound ranges.
So this is the process that is run for each of the other records S and T. I will go through each of those breifly
and only highlight the important bits.
PopulateTRec()
The T Record is basically the same thing as the F Record with the major differences being the UpperBounds and
LowerBounds. Also it looks for the T record row, naturally.
PopulateSRec()
Check out the full code for Populating the S record above or read on to learn the important bits.
As per usual varibles are defined and I get the upper and lower bounds for this section.
Using the table function in excel to get the total number of rows, each row contains all employee info.
This range is first zeroed out as per specs, it is then populated from right to left.
Here all the old data is removed if it was not previously cleared out. This is more of a quality of life
function and not strictly neccessary. The reason it is looking for "Record Identifier"
is because that is the name of the cell that is below the S record if there is only one S Record Row.
I then begin to loop through all of the employees. The CurrentRow is defined and the next
data row is inserted. Next some constant values are populated.
The Final operation is to populate the left and right justified content. There is some exeptions within the data to
how the data should be filled and so those have also been accounted for. These exceptions can be found in the Bulk
Filing Specs or in the UpperBound and LowerBound defined variables in the full code.
The ColumnNum defines the column to get the data from in the EmployeeData Sheet. i + 1
is used because i starts at 0 and tables start at 1, so row 0 does not exist.
FormatBulkFile()
The next Operation in the main function is to format the cells. This Removes some of the orginizing data that is
neccessary for creation but will no be included in the final sheet for submission. It also some does operations
because a .prn file is a pain and needs some very specific direction to work properly.
It starts by copying the first sheet which is the sheet that all data was populated into, it is renamed to
FinalFormat. Then some Organizing data is removed.
The last couple operations are for the sake of the .prn file format. First a row is add at column IF,
this is so it is easier to remove the add "i" characters. These characters are add from top to bottom
at position 240 because a .prn file can only have 240 characters perline and will remove trailing spaces after the last
character if this. This means all characters will be retained.
Lastly a ColumnWidth of 1.2 is set. This is in the range that will make the .prn file
put only one character. If this is too small the character will not be printed, if it is too large it will add extra
characters.
SaveSheet()
Next the PopulateBulkFile() saves the newly populated sheet. This would seem to be a simple
task but this is a government document so it needs to fulfill specific requirements. This involves creating
a .prn file (space delimited file type), then modifying that file because .prn files do not just work.
This function starts by moving the new FinalFormat sheet and moves it to its own workboook.
The Application.DisplayAlerts operation suppresses any warnings about overwriting a current
file if one already exists.
The file is then closed and reopened as this causes the .prn formatting to comes into play. All data is put into
the cells in column A. The data is split at 240 characters and any characters beyond this count
is put in the cells below where the last cell origonally was.
Given that this data is spit in this way I am able to grab the two cells and concatinated them. At the same time the
trailing "i"'s that were add during the formatting are dropped.
WriteTotxtRemoveQuotation()
This last function creates the txt file that will be submitted, this is is fully formatted and directly submittable
with no edits needed.
First a txt file is opened as #1 because the print statement in VBA expects a filenumber
between 1-255.
Here another querk of the .prn file format type is taken care of. It will for some reason add tabs (Chr(9))
at the end of some of the cell strings.
First the value of the cell is stored, then while the the last character of the cell value is a tab, the last character
is removed.
The last operation done for each cell is to print the new cell value without the tabs to the txt file.