在VSTO C#项目中,我想从一组行索引中获取一系列行。
行索引可以是例如“7,8,9,12,14”。
然后我想要范围“7:9,12,14”行。
我现在这样做:
Range rng1 = sheet.get_Range("A7:A9,A12,A14", Type.Missing);
rng1 = rng1.EntireRow;
但由于范围规范中的字符串处理,它的效率有点低。
sheet.Rows["7:9"]
有效,但我不能给这个
sheet.Rows["7:9,12,14"] // Fails
答案 0 :(得分:13)
试试这个:
Sheet.Range("7:9,12:12,14:14")
编辑:对不起,如果在C#中使用VSTO应该是:
sheet.get_Range("7:9,12:12,14:14", Type.Missing)
答案 1 :(得分:6)
以下是您要查找的代码:
int startRow, endRow, startCol, endCol, row,col;
var singleData = new object[col];
var data = new object[row,col];
//For populating only a single row with 'n' no. of columns.
var startCell = (Range)worksheet.Cells[startRow, startCol];
startCell.Value2 = singleData;
//For 2d data, with 'n' no. of rows and columns.
var endCell = (Range)worksheet.Cells[endRow, endCol];
var writeRange = worksheet.Range[startCell, endCell];
writeRange.Value2 = data;
您可以拥有整个范围,无论是1维还是2维单元格。
这种方法在循环遍历整个Excel工作表并在需要的时间和地点填充数据时特别有用。
答案 2 :(得分:2)
我不是C#的专家,但AFAIK你必须像上面那样使用EntireRow。您正在寻找的字符串可以从.Address
属性实现。例如
private void button1_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application xlexcel;
Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
Microsoft.Office.Interop.Excel.Range xlRange;
object misValue = System.Reflection.Missing.Value;
xlexcel = new Excel.Application();
xlWorkBook = xlexcel.Workbooks.Add();
// Set Sheet 1 as the sheet you want to work with
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlRange = xlWorkSheet.get_Range("A7:A9,A12,A14", misValue);
MessageBox.Show(xlRange.EntireRow.Address);
xlRange = xlWorkSheet.get_Range(xlRange.EntireRow.Address, misValue);
MessageBox.Show(xlRange.Address);
}
所以你可以把上面的内容写成
private void button1_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application xlexcel;
Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
Microsoft.Office.Interop.Excel.Range xlRange;
object misValue = System.Reflection.Missing.Value;
xlexcel = new Excel.Application();
xlWorkBook = xlexcel.Workbooks.Add();
// Set Sheet 1 as the sheet you want to work with
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlRange = xlWorkSheet.get_Range("$7:$9,$12:$12,$14:$14", misValue);
MessageBox.Show(xlRange.Address);
}
参见
部分 xlRange = xlWorkSheet.get_Range("$7:$9,$12:$12,$14:$14", misValue);
答案 3 :(得分:1)
Reafidy's edited answer is a great start,但我想在评论中扩展它。 sheet.get_Range(rangeselect)
比逐行更快,但我还没有看到的一件事是 get_Range参数的字符数限制为255。
要绕过该限制,正常构建一组范围,如“8:8,10:13,14:55”,然后使用此代码的变体:
string rangeSelectPart;
while (rangeSelect.Length >= 255)
{
rangeSelectPart = rangeSelect.Substring(0, rangeSelect.Substring(0,255).LastIndexOf(','));
Range multiRangePart = sheet.get_Range(rangeSelectPart, Type.Missing);
//do something with the range here using multiRangePart
rangeSelect= rangeSelect.Substring(rangeSelectPart.Length + 1);
}
Range multiRange = sheet.get_Range(rangeSelect, Type.Missing);
// do the same something with the last part of the range using multiRange
// now that the remaining rows are described in less than 255 characters
这比在单个行上执行操作要快得多,但在呈现大型非连续行集时也不会失败。
请注意,SutharMonil's answer is way faster IFF设置连续矩形范围内的值。从C#到excel的瓶颈通常是通过COM对象的重复调用,这些对象在创建和更新时会阻塞,并且他的答案可以很好地整合调用。
不幸的是,到目前为止,在我的测试中,尝试使用它来处理非字符串类型的非字符串属性会导致类型错误。例如:
object[,] colors;
//use C# to set appropriate colors to each location in array...
for(int i = 0; i < colors.get_Length(0); i++){
for(int j = 0; j < colors.get_Length(1); j++){
colors[i,j] = XlThemeColor.xlThemeColorAccent6;
}
}
//below causes a type error
formatRange.Interior.ThemeColor = color;
如果我让它工作,我会记得更新。
最后,对于重复操作设置Globals.ThisAddIn.Application.ScreenUpdating = false;
,然后在完成后将其设置为true。如果没有这个,Excel会在每组范围属性更新后停止更新屏幕,这会给操作增加很多时间。
答案 4 :(得分:0)
此代码根据条件为范围单元格指定颜色:
using Microsoft.Office.Interop.Excel;
(...)
var excel = new Application { Visible = true };
Workbook workbook = excel.Workbooks.Add(XlSheetType.xlWorksheet);
Worksheet sheet = workbook.Sheets[1];
var i = 2;
foreach (Data d in this.Datos)
{
sheet.Cells[i, 1].Value = d.Fecha;
sheet.Cells[i, 2].Value = d.Ubicacion;
sheet.Cells[i, 3].Value = d.Lote;
sheet.Cells[i, 4].Value = d.ArticuloId;
sheet.Cells[i, 5].Value = d.Articulo;
sheet.Cells[i, 6].Value = d.ColorId;
sheet.Cells[i, 7].Value = d.Color;
sheet.Cells[i, 8].Value = d.StockOriginal;
sheet.Cells[i, 9].Value = d.Diferencia;
sheet.Cells[i, 10].Value = d.StockFinal;
if (d.BackGroundColor == "#FFA061")
sheet.Range[sheet.Cells[i, 1], sheet.Cells[i, 10]].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.FromArgb(255, 160, 97));
i++;
}