I'm trying to copy data from a worksheet to another worksheet with some modifications made on the fly. Here are the details of the stuff I'm trying to do:
Open the file from where I'm going to copy data from (
xlsPath
) using OpenFileDialogCheck the sheet's cell value V6. If it is empty then write something e.g. "na"
Open the destination worksheet (if already exists) or create a new one (
dbFilePath
)Get the last filled row of both the worksheets
Set some cell formatting in both the sheets
Then copy data from
xlsPath
todbFilePath
. Some columns data are just simply copied but the first column data in thexlsPath
is modified according to what the cell V6 in that worksheet containsThen in the destination worksheet
dbFilePath
a search & replace is performed to remove the word "M/s", then all the cells are checked for leading or trailing whitespaces and performed a Trim.Then the destination worksheet is checked for duplicate rows and removed them if any.
Then the destination worksheet is checked for near duplicate rows i.e. row where the values from column 1 to column 5 are same just the value in column 6 and onwards is different, then in that case find those near identical rows (if any) and then replace them with only one row where the values from column 1 to column 5 are same as before just the value in column 6 is the sum of all the column 6 values of those near identical rows.
Finally do a autofit column, sort and save.
Here's my code
private void button2_Click(object sender, EventArgs e)
{
string xlsPath = "";
string btnTxt = btnUpdate.Text;
var err = new List<string>();
comboBox1.Text = "";
OpenFileDialog openFileDialog1 = new OpenFileDialog
{
InitialDirectory = @"D:\",
Title = "Browse Excel Files",
CheckFileExists = true,
CheckPathExists = true,
DefaultExt = "xlsx",
Filter = "Excel files (*.xlsx)|*.xlsx",
FilterIndex = 2,
RestoreDirectory = true,
ReadOnlyChecked = true,
ShowReadOnly = true
};
btnUpdate.Text = "Processing...";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
xlsPath = openFileDialog1.FileName;
Workbook workbook = new Workbook();
workbook.LoadFromFile(xlsPath);
Worksheet sheet = workbook.Worksheets[0];
//check the value of the cell V6
if (sheet.Range["V6"].Value2 == "")
{
sheet.Range["V6"].Text = "na";
}
//check if the destination file already exists or not. If not create one in the else statement
if (File.Exists(dbFilePath))
{
Workbook newBook = new Workbook();
newBook.LoadFromFile(dbFilePath);
Worksheet newSheet = newBook.Worksheets[0];
//find the last filled rows of both the worksheets
int lFilledRow = newSheet.LastRow;
for (int j = newSheet.LastRow; j >= 0; j--)
{
CellRange lcr = newSheet.Rows[j - 1].Columns[1];
if (!lcr.IsBlank)
{
lFilledRow = j + 1;
break;
}
}
int lastFilledRow = sheet.LastRow;
for (int i = sheet.LastRow; i >= 0; i--)
{
CellRange cr = sheet.Rows[i - 1].Columns[1];
if (!cr.IsBlank)
{
lastFilledRow = i;
break;
}
}
//set some number formatting in the source sheet
sheet.Range["B5:B" + lastFilledRow].NumberFormat = "dd-MM-yyyy";
sheet.Range["N5:N" + lastFilledRow].NumberFormat = "dd-MM-yyyy";
sheet.Range["W5:W" + lastFilledRow].NumberFormat = "0.00";
//replace the first column values depending on the cell V6 value i.e. if cell V6 starts with "RAW MATERIAL"
//then change all the rows column 1 value from something like '1' to 'RM-2021-22/1'
//if it starts with "PACKING MATERIAL" then change to 'PM-2021-22/1' & so on
//----------------------------------------------------------------------
if (sheet.Range["V6"].Text.StartsWith("RAW MATERIAL"))
{
for (int y = 6; y <= lastFilledRow; y++)
{
string myFormula = "=IF(MONTH($B" + y + ")>3,YEAR($B" + y + ")&\"-\"&RIGHT((YEAR($B" + y + ")+1),2), YEAR($B" + y + ")-1&\"-\"&RIGHT(YEAR($B" + y + "),2)";
object formulaResult = workbook.CaculateFormulaValue(myFormula);
string value = "RM-" + formulaResult.ToString() + "/" + sheet.Range[y, 1].Value.ToString();
sheet.Range[y, 1].Text = value;
}
}
else if (sheet.Range["V6"].Text.StartsWith("PACKING MATERIAL"))
{
for (int y = 6; y <= lastFilledRow; y++)
{
string myFormula = "=IF(MONTH($B" + y + ")>3,YEAR($B" + y + ")&\"-\"&RIGHT((YEAR($B" + y + ")+1),2), YEAR($B" + y + ")-1&\"-\"&RIGHT(YEAR($B" + y + "),2)";
object formulaResult = workbook.CaculateFormulaValue(myFormula);
string value = "PM-" + formulaResult.ToString() + "/" + sheet.Range[y, 1].Value.ToString();
sheet.Range[y, 1].Text = value;
}
}
else if (sheet.Range["V6"].Text.StartsWith("PURCHASE"))
{
for (int y = 6; y <= lastFilledRow; y++)
{
string myFormula = "=IF(MONTH($B" + y + ")>3,YEAR($B" + y + ")&\"-\"&RIGHT((YEAR($B" + y + ")+1),2), YEAR($B" + y + ")-1&\"-\"&RIGHT(YEAR($B" + y + "),2)";
object formulaResult = workbook.CaculateFormulaValue(myFormula);
string value = "FG-" + formulaResult.ToString() + "/" + sheet.Range[y, 1].Value.ToString();
sheet.Range[y, 1].Text = value;
}
}
else
{
for (int y = 6; y <= lastFilledRow; y++)
{
string myFormula = "=IF(MONTH($B" + y + ")>3,YEAR($B" + y + ")&\"-\"&RIGHT((YEAR($B" + y + ")+1),2), YEAR($B" + y + ")-1&\"-\"&RIGHT(YEAR($B" + y + "),2)";
object formulaResult = workbook.CaculateFormulaValue(myFormula);
string value = "OTH-" + formulaResult.ToString() + "/" + sheet.Range[y, 1].Value.ToString();
sheet.Range[y, 1].Text = value;
}
}
//----------------------------------------------------------------------
//simply copy data from one worksheet to another
sheet.Copy(sheet.Range["B6:B" + lastFilledRow], newSheet.Range["B" + lFilledRow], true);
sheet.Copy(sheet.Range["A6:A" + lastFilledRow], newSheet.Range["A" + lFilledRow], true);
sheet.Copy(sheet.Range["D6:D" + lastFilledRow], newSheet.Range["C" + lFilledRow], true);
sheet.Copy(sheet.Range["K6:K" + lastFilledRow], newSheet.Range["D" + lFilledRow], true);
sheet.Copy(sheet.Range["M6:M" + lastFilledRow], newSheet.Range["E" + lFilledRow], true);
sheet.Copy(sheet.Range["N6:N" + lastFilledRow], newSheet.Range["F" + lFilledRow], true);
sheet.Copy(sheet.Range["W6:W" + lastFilledRow], newSheet.Range["G" + lFilledRow], true);
//set some number formatting in the destination sheet
newSheet.Range["G2:G" + lastFilledRow].NumberFormat = "0.00";
//Remove the word "M/S"
CellRange[] ranges = newSheet.FindAllString("M/S", false, false);
foreach (CellRange range in ranges)
{
range.Text = range.Text.Replace("M/S", "");
}
//trim leading & trailing whitespaces
for (int i = 1; i <= newSheet.LastRow; i++)
{
for (int j = 1; j <= newSheet.LastColumn; j++)
{
CellRange range = newSheet.Range[i, j];
String str = range.Value;
String strings = str.Trim();
range.Value = strings;
}
}
//remove duplicate rows
//----------------------------------------------------------------------
for (int i = 0; i < newSheet.Columns[0].Count - 1; i++)
{
for (int j = i + 1; j < newSheet.Columns[0].Count; j++)
{
if (newSheet.Columns[0].CellList[i].Value == newSheet.Columns[0].CellList[j].Value)
{
for (int col = 0; col < newSheet.Rows[0].Count; col++)
{
if (col == newSheet.Rows[0].Count - 1 && newSheet.Rows[i].CellList[col].Value == newSheet.Rows[j].CellList[col].Value)
{
newSheet.DeleteRow(j + 1);
j--;
}
else if (col != newSheet.Rows[0].Count - 1 && newSheet.Rows[i].CellList[col].Value == newSheet.Rows[j].CellList[col].Value)
{
continue;
}
else
{
break;
}
}
}
}
}
//----------------------------------------------------------------------
//sort & autofit columns and save the file
newSheet.AllocatedRange.AutoFitColumns();
newBook.DataSorter.SortColumns.Add(1, OrderBy.Ascending);
newBook.DataSorter.Sort(newSheet.AllocatedRange);
newBook.SaveToFile(dbFilePath, ExcelVersion.Version2013);
newBook.Dispose();
}
else
{ //same as in the above if statement
//----------------------------------------------------------------------
Workbook newBook = new Workbook();
Worksheet newSheet = newBook.Worksheets[0];
int lastFilledRow = sheet.LastRow;
for (int i = sheet.LastRow; i >= 0; i--)
{
CellRange cr = sheet.Rows[i - 1].Columns[1];
if (!cr.IsBlank)
{
lastFilledRow = i;
break;
}
}
newSheet.Range[1, 1].Value = "BP No./REF.No.";
newSheet.Range[1, 2].Value = "BP Date";
newSheet.Range[1, 3].Value = "NAME";
newSheet.Range[1, 4].Value = "GSTIN";
newSheet.Range[1, 5].Value = "Bill No.";
newSheet.Range[1, 6].Value = "Bill Date";
newSheet.Range[1, 7].Value = "Bill Value";
newSheet.Range[1, 8].Value = "Remarks";
sheet.Range["B5:B" + lastFilledRow].NumberFormat = "dd-MM-yyyy";
sheet.Range["N5:N" + lastFilledRow].NumberFormat = "dd-MM-yyyy";
sheet.Range["Y5:Y" + lastFilledRow].NumberFormat = "0.00";
if (sheet.Range["V6"].Text.StartsWith("RAW MATERIAL"))
{
for (int y = 6; y <= lastFilledRow; y++)
{
string myFormula = "=IF(MONTH($B" + y + ")>3,YEAR($B" + y + ")&\"-\"&RIGHT((YEAR($B" + y + ")+1),2), YEAR($B" + y + ")-1&\"-\"&RIGHT(YEAR($B" + y + "),2)";
object formulaResult = workbook.CaculateFormulaValue(myFormula);
string value = "RM-" + formulaResult.ToString() + "/" + sheet.Range[y, 1].Value.ToString();
sheet.Range[y, 1].Text = value;
}
}
else if (sheet.Range["V6"].Text.StartsWith("PACKING MATERIAL"))
{
for (int y = 6; y <= lastFilledRow; y++)
{
string myFormula = "=IF(MONTH($B" + y + ")>3,YEAR($B" + y + ")&\"-\"&RIGHT((YEAR($B" + y + ")+1),2), YEAR($B" + y + ")-1&\"-\"&RIGHT(YEAR($B" + y + "),2)";
object formulaResult = workbook.CaculateFormulaValue(myFormula);
string value = "PM-" + formulaResult.ToString() + "/" + sheet.Range[y, 1].Value.ToString();
sheet.Range[y, 1].Text = value;
}
}
else if (sheet.Range["V6"].Text.StartsWith("PURCHASE"))
{
for (int y = 6; y <= lastFilledRow; y++)
{
string myFormula = "=IF(MONTH($B" + y + ")>3,YEAR($B" + y + ")&\"-\"&RIGHT((YEAR($B" + y + ")+1),2), YEAR($B" + y + ")-1&\"-\"&RIGHT(YEAR($B" + y + "),2)";
object formulaResult = workbook.CaculateFormulaValue(myFormula);
string value = "FG-" + formulaResult.ToString() + "/" + sheet.Range[y, 1].Value.ToString();
sheet.Range[y, 1].Text = value;
}
}
else
{
for (int y = 6; y <= lastFilledRow; y++)
{
string myFormula = "=IF(MONTH($B" + y + ")>3,YEAR($B" + y + ")&\"-\"&RIGHT((YEAR($B" + y + ")+1),2), YEAR($B" + y + ")-1&\"-\"&RIGHT(YEAR($B" + y + "),2)";
object formulaResult = workbook.CaculateFormulaValue(myFormula);
string value = "OTH-" + formulaResult.ToString() + "/" + sheet.Range[y, 1].Value.ToString();
sheet.Range[y, 1].Text = value;
}
}
sheet.Copy(sheet.Range["B6:B" + lastFilledRow], newSheet.Range["B2"], true);
sheet.Copy(sheet.Range["A6:A" + lastFilledRow], newSheet.Range["A2"], true);
sheet.Copy(sheet.Range["D6:D" + lastFilledRow], newSheet.Range["C2"], true);
sheet.Copy(sheet.Range["K6:K" + lastFilledRow], newSheet.Range["D2"], true);
sheet.Copy(sheet.Range["M6:M" + lastFilledRow], newSheet.Range["E2"], true);
sheet.Copy(sheet.Range["N6:N" + lastFilledRow], newSheet.Range["F2"], true);
sheet.Copy(sheet.Range["W6:W" + lastFilledRow], newSheet.Range["G2"], true);
newSheet.Range["G2:G" + lastFilledRow].NumberFormat = "0.00";
for (int i = 0; i < newSheet.Columns[0].Count - 1; i++)
{
for (int j = i + 1; j < newSheet.Columns[0].Count; j++)
{
if (newSheet.Columns[0].CellList[i].Value == newSheet.Columns[0].CellList[j].Value)
{
for (int col = 0; col < newSheet.Rows[0].Count; col++)
{
if (col == newSheet.Rows[0].Count - 1 && newSheet.Rows[i].CellList[col].Value == newSheet.Rows[j].CellList[col].Value)
{
newSheet.DeleteRow(j + 1);
j--;
}
else if (col != newSheet.Rows[0].Count - 1 && newSheet.Rows[i].CellList[col].Value == newSheet.Rows[j].CellList[col].Value)
{
continue;
}
else
{
break;
}
}
}
}
}
CellRange[] ranges = newSheet.FindAllString("M/S", false, false);
foreach (CellRange range in ranges)
{
range.Text = range.Text.Replace("M/S", "");
}
for (int i = 1; i <= newSheet.LastRow; i++)
{
for (int j = 1; j <= newSheet.LastColumn; j++)
{
CellRange range = newSheet.Range[i, j];
String str = range.Value;
String strings = str.Trim();
range.Value = strings;
}
}
newSheet.AllocatedRange.AutoFitColumns();
newBook.DataSorter.SortColumns.Add(1, OrderBy.Ascending);
newBook.DataSorter.Sort(newSheet.AllocatedRange);
newBook.SaveToFile(dbFilePath, ExcelVersion.Version2013);
newBook.Dispose();
}
workbook.Dispose();
//----------------------------------------------------------------------
}
//add the items of the above saved worksheets 3rd column (unique ones) to the combo box
//----------------------------------------------------------------------
try
{
Workbook wrkbk = new Workbook();
wrkbk.LoadFromFile(dbFilePath);
Worksheet sh = wrkbk.Worksheets[0];
List<CellRange> crs = sh.Columns[2].CellList;
foreach (CellRange cr in crs)
{
if (!String.IsNullOrEmpty(cr.Value2.ToString()) && !comboBox1.Items.Contains(cr.Value))
{
comboBox1.Items.Add(cr.Value);
}
}
comboBox1.Items.Remove("NAME");
int index = 0;
for (int i = 0; i < sh.LastColumn; i++)
{
if (sh.Rows[0].Cells[i].DisplayedText.Equals(headers[index]))
{
columnsIndexs[index] = i;
index++;
if (index == 5)
{
break;
}
}
}
wrkbk.Dispose();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
//----------------------------------------------------------------------
//find near duplicate rows and replace all near identical ones with one row with the column 6 data sum
//----------------------------------------------------------------------
Workbook nwrkbk = new Workbook();
nwrkbk.LoadFromFile(dbFilePath);
Worksheet nsh = nwrkbk.Worksheets[0];
int colCount = nsh.Rows[0].Count;
float sum;
for (int i = 1; i < nsh.Columns[0].Count - 1; i++)
{
//Delete blank row
if (nsh.Rows[i].IsBlank)
{
nsh.DeleteRow(i + 1);
i--;
}
sum = (float)nsh.Columns[colCount - 2].Rows[i].NumberValue;
for (int j = i + 1; j < nsh.Columns[0].Count; j++)
{
if (nsh.Columns[0].CellList[i].Value == nsh.Columns[0].CellList[j].Value)
{
for (int col = 1; col < nsh.Rows[0].Count - 1; col++)
{
if (col == nsh.Rows[0].Count - 3 && nsh.Rows[i].CellList[col].Value == nsh.Rows[j].CellList[col].Value)
{
sum += (float)nsh.Columns[colCount - 2].Rows[j].NumberValue;
nsh.DeleteRow(j + 1);
j--;
}
else if (col != nsh.Rows[0].Count - 3 && nsh.Rows[i].CellList[col].Value == nsh.Rows[j].CellList[col].Value)
{
continue;
}
else
{
break;
}
}
}
}
nsh.Columns[colCount - 2].Rows[i].NumberValue = sum;
}
nwrkbk.Save();
nwrkbk.Dispose();
//----------------------------------------------------------------------
//check the worksheet if any cell in the 5th column has a date in it
//----------------------------------------------------------------------
Workbook _nwrkbk = new Workbook();
_nwrkbk.LoadFromFile(dbFilePath);
Worksheet wksh = _nwrkbk.Worksheets[0];
int _lastFilledRow = wksh.LastRow;
for (int i = wksh.LastRow; i >= 0; i--)
{
CellRange cr = wksh.Rows[i - 1].Columns[1];
if (!cr.IsBlank)
{
_lastFilledRow = i;
break;
}
}
foreach (CellRange rng in wksh.Range["E2:E" + _lastFilledRow])
{
if (rng.HasDateTime)
{
err.Add(rng.Row.ToString());
}
}
if (err.Any())
{
MessageBox.Show("Some Invoice/Bill numbers are in DATE format!!\nPlease check the following rows:\n" + string.Join(", ", err));
}
MessageBox.Show("Updated!");
//----------------------------------------------------------------------
btnUpdate.Text = btnTxt;
}
I know there is a lot of Repetitive code but struggling to make them shorter, faster & more efficient.
NOTE: I'm using spire.xls for worksheet data manipulation
The source excel file looks like
The destination file looks like