private void RunCombine() { if (ctrlRefA.IsEmpty || ctrlRefA.Range == null) throw new InputError("Selection 1 is empty or incorrect."); if (ctrlRefB.IsEmpty || ctrlRefB == null) throw new InputError("Selection 2 is empty or incorrect."); //Shrink to used range Excel.Range rgSel1 = _excelapp.Intersect(ctrlRefA.Range, ctrlRefA.Range.Worksheet.UsedRange); if (rgSel1 == null) throw new InputError("Selection 1 is incorrect!"); Excel.Range rgSel2 = _excelapp.Intersect(ctrlRefB.Range, ctrlRefB.Range.Worksheet.UsedRange); if (rgSel2 == null) throw new InputError("Selection 2 is incorrect!"); //Define data range int nbRow1 = rgSel1.Rows.Count, nbCol1 = rgSel1.Columns.Count; int nbRow2 = rgSel2.Rows.Count, nbCol2 = rgSel2.Columns.Count; int offsetRow1 = ctrlWithHeadersA.Checked ? 1 : 0; int offsetRow2 = ctrlWithHeadersB.Checked ? 1 : 0; Excel.Range rgData1 = rgSel1.Offset[offsetRow1, Type.Missing].Resize[nbRow1 - offsetRow1, Type.Missing]; Excel.Range rgData2 = rgSel2.Offset[offsetRow2, Type.Missing].Resize[nbRow2 - offsetRow2, Type.Missing]; if (rgData1 == null) throw new InputError("Selection 1 is empty."); if (rgData2 == null) throw new InputError("Selection 2 is empty."); if (rgData1.Cells.Count < 2) throw new InputError("Selection 1 must contain at least 2 cells."); if (rgData2.Cells.Count < 2) throw new InputError("Selection 2 must contain at least 2 cells."); //read data int[] keysColA = ctrlKeysA.CheckedIds; int[] keysColB = ctrlKeysB.CheckedIds; if (ctrlKeysA.IsEmpty) throw new InputError("Rows identifiers for selection 1 are missing."); if (ctrlKeysB.IsEmpty) throw new InputError("Rows identifiers for selection 2 are missing."); if (keysColA.Length != keysColB.Length) throw new InputError("Number of identifiers is different."); object[,] data1 = Utils.GetDataFromRange(rgData1, false); object[,] data2 = Utils.GetDataFromRange(rgData2, false); object[,] titles1 = Utils.GetTitlesFromRange(rgSel1, offsetRow1 != 0); object[,] titles2 = Utils.GetTitlesFromRange(rgSel2, offsetRow2 != 0); int[] valColA = Utils.GetVisibleColumnsPosition(rgData1, null, keysColA); int[] valColB = Utils.GetVisibleColumnsPosition(rgData2, null, keysColB); object[] formats1 = Utils.GetColumnsFormating(rgData1); object[] formats2 = Utils.GetColumnsFormating(rgData2); //Initilise compare class and save seeting Excel._Worksheet worksheet = null; var compare = new Compare { IgnoreCase = ctrlIgnoreCase.Checked }; SaveSettings(); RowSet dataCols = compare.CombineColumns(ref data1, ref data2, ref titles1, ref titles2, keysColA, keysColB, valColA, valColB); Excel.Range rgTarget = null; if (ctrlOptSelection.Checked) { worksheet = (Excel.Worksheet)_workbook.ActiveSheet; rgSel1.Clear(); rgSel2.Clear(); rgSel1.EntireRow.Hidden = false; rgSel2.EntireRow.Hidden = false; rgSel1.EntireColumn.Hidden = false; rgSel2.EntireColumn.Hidden = false; rgTarget = rgData1.Resize[dataCols.RowLen, dataCols.ColLen]; } else if (ctrlOptNewSheet.Checked) { worksheet = (Excel.Worksheet)_workbook.Sheets.Add(Missing, _workbook.Sheets[_workbook.Sheets.Count], Missing, Missing); rgTarget = ((Excel.Range)worksheet.Cells[1 + offsetRow1, 1]).Resize[dataCols.RowLen, dataCols.ColLen]; worksheet.Activate(); } //Copy formats int c = 0; foreach (int i in keysColA) ((Excel.Range)rgTarget.Columns[++c]).NumberFormat = formats1[i - 1]; foreach (int i in valColA) ((Excel.Range)rgTarget.Columns[++c]).NumberFormat = formats1[i - 1]; foreach (int i in valColB) ((Excel.Range)rgTarget.Columns[++c]).NumberFormat = formats2[i - 1]; //copy data if (ctrlWithHeadersA.Checked) Utils.AddTitlesToRange((Excel.Range)rgTarget.Rows[0], dataCols.Titles); Utils.AddDataToRange(rgTarget, dataCols.Data); Utils.AddTagsToRange(rgTarget, dataCols.Diff, ctrlInteriorColor.SelectedColor, ctrlFontColor.SelectedColor); }