但是,如果您使用的是 R,那么您肯定已经访问过这个 RDCOMClient 库,但它只是一个与各种客户端一起工作的接口,而没有完全可以进行解锁的内置函数。
所以我有一个解决方法。我使用RDCOMClient 与启用宏的 Excel VBA 文件进行交互,该文件执行解锁。
我创建了启用宏的 Excel (macro_unlocker.xlsm),启用了开发人员选项并编写了这个 VBA 代码,该代码将从 R 中获取文件名和密码并将文件解锁为 Excel 程序,
Public Sub unlock_file(filename, pwd)
Dim wb As Workbook
Dim filename_path As String
filename_path = filename
'MsgBox filename_path & " " & pwd
Set wb = Workbooks.Open(filename:=filename, Password:=pwd)
save_filepath = Split(filename, ".xlsx")(0) & "_unlocked.xlsx"
wb.SaveAs filename:=save_filepath, Password:=""
End Sub
RDCOMClient 通过将参数传递给 VBA 脚本与 VBA 交互。它通过将密码设置为空字符串来解锁文件。
然后在 R 中,我可以编写一个函数来将参数传递给它。这就是我所拥有的,我把它放在一个名为 myUtils.R 的外部 R 文件中,只是为了让事情更整洁,
unlock_xlsx <- function(filename, pwd){
if (!require("pacman")) install.packages("pacman")
pacman::p_load(devtools)
devtools::install_github("dkyleward/RDCOMClient")
library(RDCOMClient)
# Open a specific workbook in Excel:
xlApp <- COMCreate("Excel.Application")
xlWbk <- xlApp$Workbooks()
xlWbk$Open(paste(getwd(), "/<utils folder>/macro_unlocker.xlsm",sep=""))
# this line of code might be necessary if you want to see your spreadsheet:
xlApp[['Visible']] <- TRUE
# Run the macro:
xlApp$Run("unlock_file", filename, pwd)
# Close the workbook and quit the app:
xlWbk$Close(FALSE)
xlApp$Quit()
}
所以最后要在 R 中运行函数和 VBA 宏,以便我可以以编程方式解锁文件并完成我在 R 中编写的工作,
# call in myUtils.R where the function unlock_xlsx resides
source(paste(getwd(), "./myUtils.R", sep=""))
# file to unlock
password_locked_file_FILEPATH <- Sys.glob(file.path("<sub-folder>", "<sub-folder>","<an_excel.xlsx>"))
# send the file_filepath to the function
file_to_unlock <- paste("../", password_locked_file_FILEPATH, sep="")
password_locked_file_pwd <- "<password>"
# result will be suffixed with '_unlocked' followed by '.xlsx'
unlock_xlsx(filename = file_to_unlock, pwd = password_locked_file_pwd)
多田!该文件已解锁并使用后缀_unlocked 保存。而且您绝对可以循环浏览要解锁的文件并提供相应的密码,一切都会像发条一样工作。
只要您的机器上安装了 R 和 Excel,它就可以工作。
注意:我知道RDCOMClient 的安装存在一些问题,它与最新的 R 版本 3.6 不兼容。我通过安装 dkyleward/RDCOMClient 找到了解决方法,它在 Windows 机器上安装得很好,但在 MacOS 上却失败了。