我能够根据@n8 的建议找到合适的解决方案。这个想法是使用 VBA 代码,该代码将在所有工作簿和所有列上执行文本列。然后使用 VBscript 从 R 调用此 VBA 代码。
这里是 R 代码:
library(xlsx)
wb = loadWorkbook("./source/template.xlsm")
sh = wb$getSheet("CAN.FI")
cell = CellBlock(sheet = sh, startRow = 2, startColumn = 2, noRows = 1, noColumns = 1)
CB.setMatrixData(cellBlock = cell, x = as.matrix('=SUM(A1:A2)'), startRow = 1, startColumn = 1)
cell = CellBlock(sheet = sh, startRow = 4, startColumn = 4, noRows = 1, noColumns = 1)
CB.setMatrixData(cellBlock = cell, x = as.matrix('=SUM(A1:A2)'), startRow = 1, startColumn = 1)
saveWorkbook(wb, file = "./test.xlsm")
path_to_vbs_file = "./text_to_column.vbs"
shell(shQuote(normalizePath(path_to_vbs_file)), "cscript", flag = "//nologo")
文件template.xlsm是一个空的.xlsm工作簿,带有一张CAN.FI,该书有一个嵌入的宏/模块,称为“text_to_column()”,宏如下:
Sub text_to_column()
Application.ScreenUpdating = False
On Error Resume Next
For Each wksht In ActiveWorkbook.Worksheets
wksht.activate
For Each col In wksht.Columns
Columns(col.Column).TextToColumns _
Destination:=Cells(1, col.Column), _
DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, _
ConsecutiveDelimiter:=False, _
Tab:=True, _
Semicolon:=False, _
Comma:=False, _
Space:=False, _
Other:=False, _
FieldInfo:=Array(1, 1), _
TrailingMinusNumbers:=True
Next col
Next wksht
End Sub
您会在 R 代码的末尾注意到
path_to_vbs_file = "./text_to_column.vbs"
这指向 vbscript,它只是一个 .vbs 文件。可以从文本文件创建它并更改扩展名。我关注了主题:How To create a vbscript Stackoverflow。我的 .vbs 文件名为:text_to_column.vbs,如下所示:
Option Explicit
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open(".\test.xlsm", 0, True)
xlApp.Application.Visible = False
xlApp.DisplayAlerts = False
xlApp.Run "text_to_column"
xlApp.ActiveWorkbook.SaveAs ".\test filled.xlsx", 51
xlApp.ActiveWorkbook.Close
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
vb 脚本将打开文件 test.xlsm 运行 VBA 宏“text_to_column”,然后将文件以 xlsx 格式保存在名称“testfilled.xlsx”下
vbscript 从 R 的最后一行开始运行。
长话短说,代码 R 将打开模板,以字符串格式填充公式,调用将运行宏转换公式的 vbscript。然后将保存具有正确格式的公式的最终文件。
附带说明,如果你想写公式,你可以考虑使用 ADDRESS 和 INDIRECT 允许你使用行号和列号,这比写 A1 B2 等更容易。一个例子可能是:
SUM(INDIRECT(ADDRESS(1,1)&":"&ADDRESS(5,1)))
这将做 A1:A5 的总和。
再次感谢您的帮助,@n8。
希望对大家有所帮助。
罗曼。