using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using AdvertisingProfitControlData; namespace DataTableParsingEngine { public class RowParser { /// /// Clears and rebuilds the ad special list that is held in memory. /// This is important as this prevents this engine from grabbing the /// list from the database every time this class is called. Otherwise, /// there would be noticeable lag getting the list from the SQL server. /// public static void BuildAdSpecialListings() { AdSpecialGroups.Clear(); var db = new AdvertisingProfitControlDbContext(); AdSpecialGroups.AddRange(db.AdSpecials.Select(x => x.Name)); } private static readonly List AdSpecialGroups = new List(); private static string CheckForGroupKeyWord(string cellContents) { var keyWord = string.Empty; var query = from adI in AdSpecialGroups where adI.Equals(cellContents, StringComparison.InvariantCultureIgnoreCase) select adI; var enumerable = query as string[] ?? query.ToArray(); if (enumerable.ToArray().Length > 0) { //Grab the first object in the array and return it. keyWord = enumerable.ToArray().First(); } return keyWord; } /// /// Determines a row's status. /// /// The row from a DataGridView object to be examined. /// The row's status, such as HeaderRow or NewRow. public RowAttribute GetRowAttribute(DataGridViewRow row) { //IF the supplied row is null, then simply declare it an IncompleteRow. if (row == null) { return RowAttribute.IncompleteRow; } //IF the supplied row is a new row, by the definition of the DataGridViewRow class, then return NewRow. if (row.IsNewRow) { return RowAttribute.NewRow; } //Determine the range to use during the looping process. var headerCellIndex = row.Cells.Count == Enum.GetNames(typeof(TableGroupParser.SalesTableColumns)).Length ? (int)TableGroupParser.SalesTableColumns.IsDirty : (int)TableGroupParser.InventoryTableColumns.IsDirty; var rowContents = new List(); var rowAttribute = RowAttribute.MemberRow; //Get the contents of the row that's being examined and add then to a List array. var i = 0; foreach (DataGridViewCell cell in row.Cells) { if (cell.ColumnIndex >= headerCellIndex || cell.ColumnIndex == 0) { i++; continue; } //Strip all whitespace characters from the cell, this includes vertical tabs, newlines, and any number of spaces. var cellContentsStripped = new string(cell.EditedFormattedValue.ToString().Where(c => !char.IsWhiteSpace(c)).ToArray()); //Now remove all zeros, including any decimal points as these values are meaningless. cellContentsStripped = cellContentsStripped.Replace("0", ""); cellContentsStripped = cellContentsStripped.Replace(".", ""); if (cellContentsStripped != "") { rowContents.Add(cell.EditedFormattedValue.ToString()); } //If the first cell contains nothing, then return as IncompleteRow. else if (cellContentsStripped == "" && i == (int)TableGroupParser.SalesTableColumns.AdItem) { return RowAttribute.IncompleteRow; } i++; } //With all meaningless content removed, only actual data should be here. So if there are more then one items, than that means there are more then one //cells with meaningful data in them. Which means that this row can be a header row with member rows under it. if (rowContents.Count > 1) { rowAttribute = RowAttribute.HeaderRow; } else if (rowContents.Count == 1) //Check to see if this row is intended to be for a special ad. { var keyWord = CheckForGroupKeyWord(rowContents[0]); //IF a keyword is found then declare this row an AdSpecialRow. if (keyWord != string.Empty) { return RowAttribute.AdSpecialRow; } } return rowAttribute; } public enum RowAttribute { NewRow = 0, IncompleteRow = 1, AdSpecialRow = 2, RepeatedRow = 3, MemberRow = 4, HeaderRow = 5, UnAssigned = 6 } } }