非连续行的Excel范围到剪贴板

我有一个FindRange在我的Excel工作表中查找带有文本“€”(lblValutaTeken.Text)的行。

我需要做的是获取包含文本的行(多个!)并将其复制到剪贴板。 我的范围不是连续的行,这是我绝望的基础。

到目前为止我得到了这个

object[,] cellValues = null; try { Excel.Range currentFind = null; Excel.Range firstFind = null; var missing = Missing.Value; Excel.Range RangeWithValutaSigns = xlApp.ActiveSheet.Range("g1", "g500"); currentFind = RangeWithValutaSigns.Find(lblValutaTeken.Text, missing, Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, false, missing, missing); while (currentFind != null) { if (firstFind == null) { firstFind = currentFind; } else if (currentFind.get_Address(Excel.XlReferenceStyle.xlA1) == firstFind.get_Address(Excel.XlReferenceStyle.xlA1)) { break; } Console.WriteLine("~~~~ currentFind.Row = " + currentFind.Row); Excel.Range currentFindRow = currentFind.Range[("B" + currentFind.Row), ("H" + currentFind.Row)]; cellValues = (object[,])currentFindRow.Value2; foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(cellValues)) { string name = descriptor.Name; object value = descriptor.GetValue(cellValues); Console.WriteLine("{0}={1}", name, value); } for (int j = 1; j < 8; j++) { Console.WriteLine(cellValues[i, j].ToString()); } i = i + 1; currentFind = RangeWithValutaSigns.FindNext(currentFind); } } catch (Exception ex) { MessageBox.Show("Er is een fout gemaakt tijdens het kopiëren van de productregels uit de offerte naar het clipboard." + System.Environment.NewLine + System.Environment.NewLine + "Controleer of er een excel geopend is met daarin regels met productcodes uit de LookApp." + System.Environment.NewLine + System.Environment.NewLine + "Error message:" + System.Environment.NewLine + ex.Message); } Clipboard.SetDataObject(cellValues); 

我不知道这是否会帮助你,但这里是我的想法:如果你正在寻找具有一些文本标准的行,为什么不创build一个具有该标准的string数组,然后根据您的标准筛选您的Excel文件之后,复制这些行。

例如:

 string[] Criteria = new string[1] Criteria[0] = "Your Criteria"; (if the criteria can vary you can use * ) Criteria[1] = "Some other Criteria"; 

然后根据一个标准过滤你的Excel表格:创build一个范围:

 Xl.Range myRange = yourSheet.UsedRange; 

下一个filter

 myRange.AutoFilter(7, Criteria[0], xl.XlAutoFilterOperator.xlOr, Criteria[1], true); xl.Range my_Range= myRange.SpecialCells(xl.XlCellType.xlCellTypeVisible, Type.Missing); 

现在,您只需select并复制剩余的可见行并粘贴即可。

希望这会有一些帮助。

所以,把其他多个Q&A的答案放在一起,我提出了这个问题。 不是很优雅,但它确实是我想要的。

第1步。创build一个数据表

第2步。使用Excel.Range.Find查找具有我的valutasign的范围(=单元格)(与lblvalutasign.txt相同,例如€或$或CAD)

第3步。每次find一个范围,我使用Range.Offset将cellvalues放入我的datable在相应的列。

第4步。把整个datatable到一个datagridview。 这可以是一个不可见的datagridview,如果你想。 以您想要的方式布置datagridview。

第5步。DataGridView.SelectAll()并复制到剪贴板

 DataObject d = dataGridView1.GetClipboardContent(); Clipboard.SetDataObject(d); 

第6步。使用ctr + v粘贴到任何地方!

  Excel.Application xlApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application"); Excel.Range myRange; myRange = xlApp.ActiveSheet.UsedRange; DataTable dtProductRowsFromExcel = new DataTable(); //to save all productrows form excel offer. dtProductRowsFromExcel.Columns.Add("Code", typeof(String)); //column 1 Excel B dtProductRowsFromExcel.Columns.Add("Amount", typeof(String)); //column 2 Excel C dtProductRowsFromExcel.Columns.Add("Unit", typeof(String)); //column 3 Excel D dtProductRowsFromExcel.Columns.Add("ValutaUnit", typeof(String)); //column 4 Excel E dtProductRowsFromExcel.Columns.Add("PriceUnit", typeof(String)); //column 5 Excel F dtProductRowsFromExcel.Columns.Add("ValutaTotal", typeof(String)); //column 6 Excel G dtProductRowsFromExcel.Columns.Add("PriceTotal", typeof(String)); //column 7 Excel H try { Excel.Range currentFind = null; Excel.Range firstFind = null; var missing = Missing.Value; Excel.Range RangeWithValutaSigns = xlApp.ActiveSheet.Range("g1", "g500"); currentFind = RangeWithValutaSigns.Find(lblValutaTeken.Text, missing, Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, false, missing, missing); while (currentFind != null) { if (firstFind == null) { firstFind = currentFind; } else if (currentFind.get_Address(Excel.XlReferenceStyle.xlA1) == firstFind.get_Address(Excel.XlReferenceStyle.xlA1)) { break; } Console.WriteLine("~~~~ currentFind.Row = " + currentFind.Row); string B = currentFind.Offset[0, -5].Value2.ToString(); string C = (currentFind.Offset[0, -4].Value2 != null) ? currentFind.Offset[0, -4].Value2.ToString() : ""; string D = (currentFind.Offset[0, -3].Value2 != null) ? currentFind.Offset[0, -3].Value2.ToString() : ""; string E = (currentFind.Offset[0, -2].Value2 != null) ? currentFind.Offset[0, -2].Value2.ToString() : ""; string F = (currentFind.Offset[0, -1].Value2 != null) ? currentFind.Offset[0, -1].Value2.ToString() : ""; string G = currentFind.Value2.ToString(); string H = (currentFind.Offset[0, 1].Value2 != null) ? currentFind.Offset[0, 1].Value2.ToString() : ""; dtProductRowsFromExcel.Rows.Add(B, C, D, E, F, G, H); currentFind = RangeWithValutaSigns.FindNext(currentFind); } // to check datatable in output window use: foreach (DataRow dataRow in dtProductRowsFromExcel.Rows) { foreach (var item in dataRow.ItemArray) { Console.WriteLine(item); } } dataGridView1.ReadOnly = true; dataGridView1.RowHeadersVisible = false; dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; dataGridView1.DataSource = dtProductRowsFromExcel; dataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText; dataGridView1.SelectAll(); DataObject d = dataGridView1.GetClipboardContent(); Clipboard.SetDataObject(d); } catch (Exception ex) { MessageBox.Show("Error message:" + System.Environment.NewLine + ex.Message); }