【问题标题】:JScript using Excel TextToColumns使用 Excel TextToColumns 的 JScript
【发布时间】:2023-10-01 13:41:01
【问题描述】:

我一直在努力让这个小 sn-p 工作,但我失败得很惨。该脚本似乎可以正常工作,但问题是:我需要将第三列(带有数字的那一列)转换为文本。

查看 Excel 中的帮助页面,似乎“Array(3, 2)”部分可以实现,但即使在此函数上尝试了很多数字和参数的组合,我也无法使其工作。

对这个问题有帮助吗?

var app = new ActiveXObject("Excel.Application");
app.Visible = true;
var xls = app.Workbooks.Add();

app.Cells(1, 1).Value = "Olympia, WA, 123";
app.Cells(2, 1).Value = "Salem, OR, 3434";
app.Cells(3, 1).Value = "Boise, ID, 342";
app.Cells(4, 1).Value = "Sacramento, CA, 3";

app.Range("A1").EntireColumn.TextToColumns(app.Range("B1"),1,1,false,false,false,true,false,false,Array(3, 2));

【问题讨论】:

    标签: excel jscript wsh


    【解决方案1】:

    这里有两个问题。

    第一个问题是您用于FieldInfo 参数的格式不正确。参数应该是一个array-of-arrays。这种数组的 JScript 格式如下所示:

    // 2 = xlTextFormat
    [[1, 2], [2, 2], [3, 2]]
    // or, if you prefer using the Array() function:
    Array(Array(1, 2), Array(2, 2), Array(3, 2))
    

    (在我的测试中,我必须指定所有三列。如果您不关心其他列,请将 xlGeneralFormat 的每个数组的第二项设置为 1。)

    然而,事情并没有那么简单,因为 Excel 与大多数 COM 对象一样,期望数组是 SAFEARRAY 结构。在 VBScript 中,这不是问题,因为它的数组是使用 SAFEARRAY 实现的,但在 JScript 中,数组本质上是一种特殊类型的对象,不容易转换为 SAFEARRAY(如果需要,您可以在 this article from Eric Lippert's blog 中阅读更多内容)更多细节)。没有将 JScript 数组转换为 SAFEARRAY 的内置方法,但有一些变通方法(例如,请参阅 this SO question)。

    第二个问题是您实际上缺少一个参数,OtherChar。尽管文档声明仅当 OtherTrue 时才需要此参数,但您仍然必须提供一些值,因为 JScript 中没有可选参数。在下面的示例中,我扩展了函数调用并使用documentation 中的参数名称标记了每一行以使其清晰:

    var app = new ActiveXObject("Excel.Application");
    app.Visible = true;
    var xls = app.Workbooks.Add();
    
    app.Cells(1, 1).Value = "Olympia, WA, 123";
    app.Cells(2, 1).Value = "Salem, OR, 3434";
    app.Cells(3, 1).Value = "Boise, ID, 342";
    app.Cells(4, 1).Value = "Sacramento, CA, 3";
    
    app.Range("A1").EntireColumn.TextToColumns(
        app.Range("B1"),  // Destination
        1,                // DataType
        1,                // TextQualifier
        false,            // ConsecutiveDelimiter
        false,            // Tab
        false,            // Semicolon
        true,             // Comma
        false,            // Space
        false,            // Other
        '',               // OtherChar
        getSafeArray([
            getSafeArray([1, 2]),
            getSafeArray([2, 2]),
            getSafeArray([3, 2])
        ])                // FieldInfo
    );
    
    // ref: https://*.com/a/5910730
    function getSafeArray(jsArr) {
        var dict = new ActiveXObject("Scripting.Dictionary");
        for (var i = 0; i < jsArr.length; i++)
        dict.add(i, jsArr[i]);
        return dict.Items();
    }
    

    【讨论】:

    • 感谢 Cheran 的贡献。它不仅解决了我的问题,而且您还解释了为什么我的任何尝试都没有成功。该死的安全阵列。
    【解决方案2】:

    FieldInfo 参数需要是一个数组数组,而不是你在没有 new 的情况下调用本机 JScript Array 构造函数时返回的东西。

    所以通过单独修改列来降低复杂度:

    app.Range("A1").EntireColumn.TextToColumns(app.Range("B1"),1,1,false,false,false,true,false,false);
    app.Range("D1").EntireColumn.NumberFormat = "@"
    

    【讨论】:

    • 您好,感谢您的回答。我最后的目标是将这个 excel 文件作为数据库打开并读取它,但是列上的混合信息 excel 一直以一种奇怪的方式运行。该答案设置了列的格式,但不会将数据设为文本,因此无法解决最终目标。 =)