c# - 在 C# 中将 Excel 范围作为文本数组或单元格格式的快速方法?

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

object[,] RangeValues = wsh.get_Range("A1:" + lastCell.Address).Value2;

效果不错。可悲的是,我有一些不一致的数据。有时是0.45,有时是0.45%,当然后来我在代码中看到的是0.0045。遗憾的是,从“业务”的角度来看,这两个值都意味着 0.45。我不能强制保持一致性,文件来 self 没有任何权限的各种来源。这是我需要处理的事情。

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

object[,] RangeValues = wsh.get_Range("A1:" + lastCell.Address).Text;

我收到无法将 DBNull 转换为 object[,] 的消息。那么有没有什么方法可以让我一次加载文本或格式,而无需在 mu 循环的每一步都经过彻底的代码 工作表边框?

最佳答案

检测 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;
    } 
}

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


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

Is there any way that would allow me to load texts or formats all at once?

只需使用上述方法检测所有单元格格式(使用自动填充)并将它们添加到 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

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

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;

Excel 百分比转换技巧

I have some inconsistent data. Sometimes there is 0.45, and sometimes 0.45%

如果您遇到的唯一数据不一致是 % 值,那么这里有一个技巧。

大概百分比值会在一列中,要转换它们,请复制值列(在 A 列中):

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

右键单击 100 列中的单元格并选择选择性粘贴:

选择值并相乘:

Excel 会将它们转换为实数:

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

and of course later i see it as 0.0045 in code.

注意:代码是对的,0.45%不是45%,0.45%小于0.5%!如果某个特定客户向您发送文件,希望您违反数学定律并处理 0.45% = 45%,那么他们很有可能突然开始获得 100 倍以上或 100 倍以下的 yield 。我会礼貌地指出他们需要改变它。不要尝试围绕这个进行编程。如果这就是您要查看单元格格式的原因,那么您所做的只是排除症状,而不是修复会加剧问题并隐藏更大问题的根本原因。只需礼貌地指出您无法控制的来源,可能会出现 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;    
}

https://stackoverflow.com/questions/32047948/

相关文章:

android - 如何在 Android 上将持续时间格式化为具有本地化时间单位的字符串?

python - 我怎样才能产生一个很好的 numpy 矩阵输出?

c++ - 输出带有数字分组的数字(1000000 为 1,000,000 等等)

xml - 选择性地关闭 XML 文件的 Eclipse 格式

c++ - 使用 BOOST_FOREACH 时如何使 Eclipse CDT 自动缩进?

c# - 单元格值的条件格式

javascript - Highcharts y轴千位分隔符

python - 避免在字符串中指定相同值的最pythonic方法是什么

iphone - 时间跨度的智能格式化

latex - 如何在 LaTeX 中的空格后设置制表位?