快速获取Excel范围作为C#中的文本或单元格格式的范围?

Moł*_*łot 9 c# double excel formatting vsto

数组操作比VSTO中的范围操作快,所以目前我正在使用

object[,] RangeValues = wsh.get_Range("A1:" + lastCell.Address).Value2;
Run Code Online (Sandbox Code Playgroud)

效果很好.可悲的是,我有一些不一致的数据.有时会有0.45,有时0.45%,当然后来我会0.0045在代码中看到它.可悲的是,从"商业"的角度来看,这两个价值观都意味着0.45.我不能强制一致性,文件来自各种来源,我没有任何权限.这是我需要处理的事情.

当然,方式是查看格式或显示文本,并查看其中是否有%符号.如果有,我只需要将值乘以100.可悲的是,如果我尝试:

object[,] RangeValues = wsh.get_Range("A1:" + lastCell.Address).Text;
Run Code Online (Sandbox Code Playgroud)

我得到的消息无法转换DBNullobject[,].那么有什么方法可以让我一次加载文本或格式,而不需要在mu循环的每一步都进行彻底的代码< - >工作表边框?

Jer*_*son 6

检测Excel单元格格式

要找到单元格的格式,请使用Excel的Cell("format",A1)函数,而不是询问数据类型,这些数据类型会更慢,更难,更容易出现问题,例如:0.45%!= 45%.

在此输入图像描述

private void button1_Click(object sender, EventArgs e) 
{
    // evaluate the Format of Cells A1 thru to A7
    using (var rnEvaluate = xlApp.Range["C1:C1"].WithComCleanup())
    {
        for (int i = 1; i < 8; i++)
        {
            rnEvaluate.Resource.Value2 = "=CELL(\"format\",A" + i.ToString() + ")";
            string cellFormat = GetExcelCellFormat(rnEvaluate.Resource.Value2);
            System.Diagnostics.Debug.Write(cellFormat);
        }
    } 
}

private string GetExcelCellFormat(string cellFormat = "G") 
{
    switch (cellFormat.Substring(0, 1))
    {
        case "F" :
            return "Number";
            break;
        case "P" :
            return "Percentage";
            break;
        case "C":
            return "Currency";
            break;
        case "D":
            return "Date";
            break;
        default :
            return "General";
            break;
    } 
}
Run Code Online (Sandbox Code Playgroud)

.WithComCleanup()是因为我正在使用VSTO Contrib.


一次检测所有Excel单元格格式

有什么办法可以让我一次加载文本或格式吗?

只需使用上述方法检测所有单元格格式(使用自动填充)并将它们添加到objectArray.比方说,我想知道列A和B的单元格格式:

在此输入图像描述

使用这个VBA代码我可以获得所有单元格格式(一次不迭代单元格):

Range("C1").Select
ActiveCell.Value2 = "=CELL(""format"",A1)"
'Fill Down
Range("C1").Select
Selection.AutoFill Destination:=Range("C1:C6"), Type:=xlFillDefault
'Fill Across
Range("C1:C6").Select
Selection.AutoFill Destination:=Range("C1:D6"), Type:=xlFillDefault
Run Code Online (Sandbox Code Playgroud)

以下是转换为C#的上述VBA代码,并将这些格式存储在对象数组中:

var filepath = @"C:\temp\test\book2.xlsx";
var xlApp = new Microsoft.Office.Interop.Excel.Application();
//Optional but recommended if the user shouldn't see Excel.
xlApp.Visible = false;
xlApp.ScreenUpdating = false;
//AddToMru parameter is optional, but recommended in automation scenarios.
var workbook = xlApp.Workbooks.Open(filepath, AddToMru: false);

//This operation may take a little bit of time but no where near 15 minutes!!!
var cell = xlApp.Range["C1:C1"];
cell.Value2 = "=CELL(\"format\",A1)";
//Fill Down
cell.AutoFill(xlApp.Range["C1:C6"], Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillDefault);
//Fill Across
cell = xlApp.Range["C1:C6"];
cell.AutoFill(xlApp.Range["C1:D6"], Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillDefault);
//Get cell formats into object array
object[,] rangeFormats = xlApp.get_Range("C1:D6").Value2;
Run Code Online (Sandbox Code Playgroud)

Excel百分比转换技巧

我有一些不一致的数据.有时有0.45,有时为0.45%

如果您所拥有的唯一数据不一致是%值,那么这是一个技巧.

大概百分比值将在一列中,为了转换它们,复制值列(在A列中):

在此输入图像描述

确保设置值为100的列(如B列所示)

右键单击100列中的单元格,然后选择"选择性粘贴":

在此输入图像描述

选择值和乘法:

在此输入图像描述

Excel会将它们转换为实数:

在此输入图像描述

显然,您可以通过编程方式执行此操作.只需将操作记录为宏并将VBA转换为C#.

当然后来我在代码中看到它为0.0045.

注意:代码是对的,0.45%不是45%,0.45%不到半个百分点!如果某个特定客户向您发送文件,希望您违反数学定律并处理0.45%= 45%那么他们很可能突然开始减少100倍或100倍.我礼貌地指出他们需要改变它.不要尝试和编程这个.如果这就是你想要查看Cell Formats的原因,那么你所做的就是排除症状,而不是解决根本原因,这会加剧问题并隐藏更大的问题.只是礼貌地指出你无法控制的消息来源,x100折叠可能存在一些大问题并且坚持需要纠正.否则我希望在DailyWTF中看到一个关于它的热闹故事,其中包含以下代码:

var val = rangeValues[1,1].ToString();
var cellFormat = rangeFormat[1,1].ToString();

if (val.EndsWith("%") && val.Replace("%","") < 1 && cellFormat == "G")  {
   dailyWTFval = val.Replace("%","") * 100;
}
else
   dailyWTFval = val;    
}
Run Code Online (Sandbox Code Playgroud)