private void BtnGetSheets_Click(object sender, EventArgs e) { if (ValidationLogic.InvalidFile(TbxFilePath)) { ErrorActions.InvalidFile(); } else { try { /* using form inputs open the file and loop through all sheets within * the workbook, adding the name of each sheet encountered into a list * box that the user can select from. */ string file = TbxFilePath.Text.ToString(); ExcelThread.OpenWorkbook(file); ExcelThread.GetSheets(); LbxSheetNames.Items.Clear(); for (int i = 1; i <= ExcelThread.Worksheets.Count; i++) { Microsoft.Office.Interop.Excel.Worksheet sheet = ExcelThread.Worksheets[i]; LbxSheetNames.Items.Add(sheet.Name.ToString()); } // make the next stage of the process/application visible. GrpSheetAndHeader.Visible = true; } catch { ErrorActions.FailOpenFile(); } } }
/* this method is designed to allow the user to perform a soft reset and reset * the application to the state direcly after pressin the 'get headers or * columns' button. The intent is to allow mutiple agings of the same data * making use of different headers on subsquent agings. */ private void ReAgeCurrentFileToolStripMenuItem_Click(object sender, EventArgs e) { // subset of get sheets button event. ExcelThread.Reset(); string file = TbxFilePath.Text.ToString(); ExcelThread.OpenWorkbook(file); ExcelThread.GetSheets(); // subset of the get headers button event. if (ValidationLogic.NoItemSelected(LbxSheetNames)) { ErrorActions.NoSheetSelected(); } else { string sheetWithData = LbxSheetNames.SelectedItem.ToString(); ExcelThread.Worksheet = ExcelThread.Worksheets[sheetWithData]; if (ValidationLogic.NoColumnsFound(ExcelThread.Worksheet)) { ErrorActions.NoColumnsFound(); } else { BuildHeaders(); PrepForAging(); } } }
private void BtnRunAging_Click(object sender, EventArgs e) { if (ValidationLogic.DateInvalid(DtpAnchorDate.Value)) { ErrorActions.DateInFuture(); } else if (ValidationLogic.ColumnsNotSelected(LbxDataToAge, LbxDatesToAgeBy)) { ErrorActions.ColumnsNotSelected(); } else { // simple visibility changes are how the processing status is communicated. BtnRunAging.Visible = false; LblProcessing.Visible = true; // ensure our accumilator is ready to receive data. AgedData.Zero(); int dateColumn = LbxDatesToAgeBy.SelectedIndex + 1; // Excel arrays are not 0 based int valueColumn = LbxDataToAge.SelectedIndex + 1; // Excel arrays are not 0 based // since our data included a header we skip over the first row (i=2). for (int i = 2; i <= ExcelThread.DataSet.Rows.Count; i++) { // value2 property doesn’t use the Currency and Date data types returns as Double var rawDate = ExcelThread.DataSet.Cells[i, dateColumn].Value2; var rawVal = ExcelThread.DataSet.Cells[i, valueColumn].Value2; /* since we are not validating the existance of data within each cell in our dataset * we need to check that we sucessfully returned non-nulls. If either the value * within the 'to age' or the 'to age by' column for a given row are empty the * entire row will be skipped. This application is not intended to clean data only * process an existing proper dataset. */ if (rawDate is null || rawVal is null) { continue; } // getting the types of the data returned and also setting flags used in type checking. Type dateType = rawDate.GetType(); Type valType = rawVal.GetType(); int bucket = -1; float value = (float)-1.0; /* by using the Value2 property we ensure that dates will be read in at Doubles. Given * the stagering diversity in the way date strings are represented the decision was * made to reject any dates not formated as a date, datetime, or number within excel. */ if (dateType.Name != "Double") { ErrorActions.InvalidDataType(); } else { int daysPast = (DtpAnchorDate.Value - DateTime.FromOADate(rawDate)).Days; bucket = daysPast / (int)30; // explicitly casting denominator at int because I am paranoid. } /* if the 'to age' value read in was a double (because of using Value2) we cast it * to a float and we parse any string received into a float as well. */ if (valType.Name == "Double") { value = (float)rawVal; } else if (valType.Name == "String") { try { value = float.Parse(rawVal); } catch { ErrorActions.InvalidDataType(); } } else { ErrorActions.InvalidDataType(); } // finally we validate our type check flags and update our accumlator if (bucket == -1 || value == (float)-1.0) { ErrorActions.InvalidValue(); } else { AgedData.AddAgedData(bucket, value); } } // simple visibility and text changes are how the processing status is communicated. LblProcessing.Text = "Complete"; // text was changed to eliminate a control from the form. BtnView.Visible = true; BtnSave.Visible = true; } }
private void BuildHeaders() { if (ValidationLogic.NoItemSelected(LbxSheetNames)) { ErrorActions.NoSheetSelected(); } else { // set the specific sheet by using the selected sheet name from the list box control. string sheetWithData = LbxSheetNames.SelectedItem.ToString(); ExcelThread.Worksheet = ExcelThread.Worksheets[sheetWithData]; if (ValidationLogic.NoColumnsFound(ExcelThread.Worksheet)) { ErrorActions.NoColumnsFound(); } else { // Determine the number of columns within the sheet that are actually holding values ExcelThread.DataSet = ExcelThread.Worksheet.UsedRange; int colCount = ExcelThread.DataSet.Columns.Count; /* the following two lines are required to ensure if the user changes the value * of their answer for if headers are included and re-clicks the button the * list box control does not 'grow' with the new selection. In addition columns * to be used in the Aging process are selected by index, therefore the order of * the list box controls must not be sorted. ORDER MATTERS!!!! */ LbxDataToAge.Items.Clear(); LbxDatesToAgeBy.Items.Clear(); /* if headers exist loop through all columns and add the value of the first * row into two list box controls, what to age and what to age by. */ if (RbtHeadYes.Checked) { for (int i = 1; i <= colCount; i++) { Microsoft.Office.Interop.Excel.Range cellValue = ExcelThread.DataSet.Cells[1, i]; LbxDatesToAgeBy.Items.Add(cellValue.Value.ToString()); LbxDataToAge.Items.Add(cellValue.Value.ToString()); } // make the next stage of the process/application visible. GrpColumnAndAging.Visible = true; } /* if no headers exist add 'Column X' where X represents the column number, * into two list box controls, what to age and what to age by. */ else if (RbtHeadNo.Checked) { for (int i = 1; i <= colCount; i++) { string columnNumber = "Column " + i.ToString(); LbxDatesToAgeBy.Items.Add(columnNumber); LbxDataToAge.Items.Add(columnNumber); } // make the next stage of the process/application visible. GrpColumnAndAging.Visible = true; } else { ErrorActions.HeaderNotAnswered(); } } } }