10

在 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
4

5 回答 5

13

试试这个:

Sheet.Range("7:9,12:12,14:14")

编辑:抱歉,如果在 C# 中使用 VSTO,它应该是:

sheet.get_Range("7:9,12:12,14:14", Type.Missing)
于 2012-09-11T09:58:06.520 回答
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;

您可以拥有整个范围,无论是一维还是二维单元格数组。

在循环遍历整个 Excel 工作表并在需要的地方和时间填充数据时,此方法特别有用。

于 2012-09-12T13:04:39.287 回答
3

我不是 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);
于 2012-09-11T11:44:16.317 回答
1

Reafidy 编辑过的答案是一个很好的开始,但我想扩展它而不是发表评论。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 的答案是在连续矩形范围内更快地设置 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 会在每组范围属性更新后停止更新屏幕,这会增加操作的大量时间。

于 2017-10-23T17:31:35.640 回答
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++;
}

于 2018-03-12T11:42:09.323 回答