An Inventory Transaction Report in C#

INTRODUCTION

This discussion will focus on a C Sharp module that will accept a transaction date range input for an inventory transactions report. The programming code will show the inventory additions and subtractions that occurred within the entered transaction date range upon the report’s preview. Please click here to see the full code readout for this Microsoft Visual Studio desktop application.

GET THE DATE RANGE TO FILTER DATA FOR THE REPORT

The first thing to do is prompt the user for a transaction date range that will be used to extract data for the report. This will trap additions and subtractions of part numbers in the inventory system that fall within the date range inputs. The transaction date range input screen looks like this.

EXTRACT THE DATA FOR THE REPORT

After clicking the “Proceed” button, the detail inventory records that are trapped within the specified transaction date range will be appended to a newly created binary text file I call currdir +”ireport.txt”, where “currdir” is the path of the current directory. The date comparison process I use here explodes the dates into month, day and year components. These date elements are used in a proprietary algorithm I created that also compensates for the Y2K issue. This date comparison algorithm may seem crude and unorthodox, but it does work consistently. I have used this in many software development projects with very reliable results.

This uses a “nested looping” mechanism to extract the needed detail inventory transaction records. The master inventory data file, currdir + “mastitem.txt”, acts as the “outer loop”. “MASTERLEN” is the record length of each master inventory record used in the “outer loop”. With each pass through, the current master inventory record’s detail transaction data file name is retrieved and opened. This detail inventory transaction file acts as the “inner loop” of the data extraction algorithm. The “DETAILEN” defined constant represents the record length of each detail inventory transaction record used in the “inner loop”.

The date comparison algorithm and transaction data extraction will occur within the “inner loop”. Data from each transaction data record will be appended to the currdir + “ireport.txt” binary data file. Also, the running balance will be calculated for each line of detail transaction data that appears in the inventory transaction report.

SET UP THE PRINT PREVIEW WINDOW

The code below illustrates how the print preview window is constructed after the detail inventory transaction data has been extracted and appended to currdir +”ireport.txt”. I have set the “PageCount” variable to 1 to initialize the page counting mechanism. Also, the “master_inventory_record_increment” file stream position offset variable, has been initialized to 0.

  1.         // this will fire after clicking the 'Proceed' button on the transaction date input screen.  
  2.         private void ProceedButton_Click(object sender, System.EventArgs e)  
  3.         {  
  4. (preceding code to process data....see full code readout)             
  5. .  
  6. .  
  7. .  
  8.    
  9.           // use constructors to create objects needed to create  
  10.           // the print preview window of the report.  
  11.           PrintPreviewDialog printPreviewDialog1 = new PrintPreviewDialog();  
  12.           PrintDocument printDocument1 = new PrintDocument();  
  13.           printPreviewDialog1.Document = printDocument1;  
  14.           master_inventory_record_increment = 0;  
  15.           PageCount = 1;  
  16.           printPreviewDialog1.Size = new Size(900, 700);  
  17.           printDocument1.PrintPage += new    PrintPageEventHandler(this.printDocument1_PrintPage);  
  18.           PrintDialog d = new PrintDialog();  
  19.           d.Document = printDocument1;  
  20.           DialogResult r = d.ShowDialog();  
  21.           if (r == DialogResult.OK)  
  22.           {  
  23.              // now show the report.  
  24.              printPreviewDialog1.ShowDialog();  
  25.           }  
  26.   
  27.         } 
Next, you see the code that “paints” the print preview window so the inventory transactions report will display.
  1.         // this will render the print preview of the inventory report.  
  2.         private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs ev)  
  3.         {  
  4.   
  5. // declare local variables for the 'print' event.  
  6. float x1 = 0.0F;  
  7. float y1 = 0.0F;  
  8. float line_counter;  
  9. float width_quartervalue;  
  10. string stringDateRange;  
  11. // construct objects to facilitate the printing process.  
  12. System.Drawing.Font printFont = new System.Drawing.Font("Arial", 8, System.Drawing.FontStyle.Regular);  
  13. System.Drawing.Font printFontB = new System.Drawing.Font("Arial", 10, System.Drawing.FontStyle.Bold);  
  14. System.Drawing.Font printFontTitle = new System.Drawing.Font("Arial", 12, System.Drawing.FontStyle.Bold);  
  15. ev.Graphics.PageUnit = GraphicsUnit.Inch;  
  16. SizeF sz, sz1, sz2;  
  17.   
  18.   
  19. // set this 'width_quartervalue' variable that will  
  20. // be used to assist with centering information on  
  21. // the preview and printed output.   
  22. width_quartervalue = 8.50f / 4.0f;  
  23.   
  24.   
  25. // render the heading information: date, page number, title, etc.  
  26. DateTime saveNow = DateTime.Now;  
  27. dtString = saveNow.ToString();  
  28. ev.Graphics.DrawString(dtString, printFont, System.Drawing.Brushes.Black, x1 + 0.5f, y1 + 0.4f);  
  29. ev.Graphics.DrawString("Page: ", printFont, System.Drawing.Brushes.Black, x1 + 7.5f, y1 + 0.4f);  
  30. sz1 = ev.Graphics.MeasureString("Page: ", printFont);  
  31. ev.Graphics.DrawString(PageCount.ToString(), printFont, System.Drawing.Brushes.Black, x1 + 7.5f + sz1.Width, y1 + 0.4f);  
  32. sz = ev.Graphics.MeasureString("Items Inventory Transaction List", printFontTitle);  
  33. ev.Graphics.DrawString("Items Inventory Transaction List", printFontTitle, System.Drawing.Brushes.Black, x1 + (width_quartervalue * 2) - (sz.Width / 2), y1 + 0.5f);  
  34. stringDateRange = strStartDate.ToString() + " To " + strEndDate.ToString();  
  35. sz2 = ev.Graphics.MeasureString(stringDateRange, printFont);  
  36. ev.Graphics.DrawString(stringDateRange, printFont, System.Drawing.Brushes.Black, x1 + (width_quartervalue * 2) - (sz2.Width / 2), y1 + 0.9f);  
  37.   
  38. line_counter = 0.7f;  
  39.   
  40. // render the column labels of the report.  
  41. line_counter = line_counter + 0.10f;  
  42. ev.Graphics.DrawString("Date ", printFontB, System.Drawing.Brushes.Black, x1 + 0.5f, y1 + line_counter + 0.9f);  
  43. ev.Graphics.DrawString("P.O.# ", printFontB, System.Drawing.Brushes.Black, x1 + 1.1f, y1 + line_counter + 0.9f);  
  44. ev.Graphics.DrawString("Item ", printFontB, System.Drawing.Brushes.Black, x1 + 2.05f, y1 + line_counter + 0.9f);  
  45. ev.Graphics.DrawString("Description ", printFontB, System.Drawing.Brushes.Black, x1 + 3.35f, y1 + line_counter + 0.9f);  
  46. ev.Graphics.DrawString("Q IN ", printFontB, System.Drawing.Brushes.Black, x1 + 5.8f, y1 + line_counter + 0.9f);  
  47. ev.Graphics.DrawString("Q OUT", printFontB, System.Drawing.Brushes.Black, x1 + 6.55f, y1 + line_counter + 0.9f);  
  48. ev.Graphics.DrawString("Balance", printFontB, System.Drawing.Brushes.Black, x1 + 7.3f, y1 + line_counter + 0.9f);  
  49. line_counter = line_counter + 0.25f;  
  50.   
  51. FileInfo datafileinfo = new FileInfo(currdir + "ireport.txt");  
  52. sizeofdatafile = datafileinfo.Length;  
  53.   
  54. StreamReader streamobj = new StreamReader(currdir + "ireport.txt");  
  55. streamobj.BaseStream.Seek(master_inventory_record_increment, SeekOrigin.Begin);  
  56.   
  57.    do  
  58.    {  
  59.   
  60.     stringVal = streamobj.ReadLine();  
  61.   
  62.        if (stringVal != null)  
  63.        {  
  64.   
  65.           if (stringVal.Substring(0, 4) != "Date")  
  66.           {  
  67.   
  68.           // display the pertinent data beneath each of the column headings.  
  69.           ev.Graphics.DrawString(stringVal.Substring(0, 8), printFont, System.Drawing.Brushes.Black, x1 + 0.5f, y1 + line_counter + 0.9f);  
  70.           ev.Graphics.DrawString(stringVal.Substring(8, 10), printFont, System.Drawing.Brushes.Black, x1 + 1.1f, y1 + line_counter + 0.9f);  
  71.           ev.Graphics.DrawString(stringVal.Substring(18, 15), printFont, System.Drawing.Brushes.Black, x1 + 2.05f, y1 + line_counter + 0.9f);  
  72.           ev.Graphics.DrawString(stringVal.Substring(33, 30), printFont, System.Drawing.Brushes.Black, x1 + 3.35f, y1 + line_counter + 0.9f);  
  73.           ev.Graphics.DrawString(stringVal.Substring(63, 5), printFont, System.Drawing.Brushes.Black, x1 + 5.8f, y1 + line_counter + 0.9f);  
  74.           ev.Graphics.DrawString(stringVal.Substring(68, 5), printFont, System.Drawing.Brushes.Black, x1 + 6.55f, y1 + line_counter + 0.9f);  
  75.           ev.Graphics.DrawString(stringVal.Substring(73, 7), printFont, System.Drawing.Brushes.Black, x1 + 7.3f, y1 + line_counter + 0.9f);  
  76.           line_counter = line_counter + 0.15f;  
  77.   
  78.           }  
  79.   
  80.        }  
  81.   
  82.     master_inventory_record_increment = master_inventory_record_increment + REPORTRECORDLEN;  
  83.   
  84.     } while (line_counter < 8.0f && master_inventory_record_increment < sizeofdatafile);  
  85.     streamobj.Close();  
  86.   
  87.   
  88.   
  89. // if the filestream offset 'master_inventory_record_increment' has not reached the   
  90. // end of the data file currdir + "ireport.txt", then continue printing; otherwise stop.   
  91. if (master_inventory_record_increment < sizeofdatafile)  
  92. {  
  93. // if there are more pages in the report, then continue.  
  94. PageCount++;  
  95. ev.HasMorePages = true;  
  96. }  
  97.    else  
  98.     {  
  99.     // if there are no more pages in the report, then stop.  
  100.     ev.HasMorePages = false;  
  101.     master_inventory_record_increment = 0;  
  102.     PageCount = 1;  
  103.     }  
  104.   
  105.   
  106.         } 
 Here is a snapshot of what the first page of the print preview of the inventory transactions report looks like for an input date range of 01/01/13 through 12/31/13 using sample data.
 
 
 
 CONCLUSION

During the course of building an application, it’s important to consider the “human engineering” side of the equation. A program must be inviting to entice people to use it. This inventory transaction report is both simple to operate and fast. That is what customers really want – not some overdone programming behemoth that scares off potential users. In addition to application development, I also offer computer repair services in my local area of Cleveland, Ohio USA.