excel - 通过 VBA 将 excel 行导出到单个 XML 文件
问题描述
我正在关注这个答案(将电子表格的行转换为单独的 XML 文件),但是我收到一个错误消息,告诉我未定义对象。我很抱歉,因为我是 VBA 的新手。
我的表格遵循代码中显示的顺序,例如
- 第 1 列 {eg A} = 文件名字符串
- 列 677 {例如 ZA} = XML 文件第一行的字符串
- 第 683 列 {例如 ZG} = 视频文件的标题{此列和所有后续列已经在每行的单元格值本身中内置了相应的标签(例如 <title{>} - (<)/title>)}
我产生错误的代码是:
Sub testXLStoXML()
sTemplateXML = _
"<xml_version>" + vbNewLine + _
"<xml_movie>" + vbNewLine + _
"<plot>" + vbNewLine + _
"<xml_outline>" + vbNewLine + _
"<xml_lockdata>" + vbNewLine + _
"<dateadded>" + vbNewLine + _
"<title>" + vbNewLine + _
"<rating>" + vbNewLine + _
"<year>" + vbNewLine + _
"<sorttile>" + vbNewLine + _
"<mpaa>" + vbNewLine + _
"<premiered>" + vbNewLine + _
"<releasedate>" + vbNewLine + _
"<runtime>" + vbNewLine + _
"<studio>" + vbNewLine + _
"<1>" + vbNewLine + _
"<2>" + vbNewLine + _
"<3>" + vbNewLine + _
"<folder>" + vbNewLine + _
"</data>" + vbNewLine
Set doc = CreateObject("MSXML2.DOMDocument")
doc.async = False
doc.validateOnParse = False
doc.resolveExternals = False
With ActiveWorkbook.Worksheets(1)
lLastRow = .UsedRange.Rows.Count
For lRow = 2 To lLastRow
sFile = .Cells(lRow, 2).Value
sXml_version = .Cells(lRow, 677).Value
sXml_movie = .Cells(lRow, 678).Value
sPlot = .Cells(lRow, 679).Value
sXml_outline = .Cells(lRow, 680).Value
sXml_lockdata = .Cells(lRow, 681).Value
sDateadded = .Cells(lRow, 682).Value
sTitle = .Cells(lRow, 683).Value
sRating = .Cells(lRow, 684).Value
sYear = .Cells(lRow, 685).Value
sSorttile = .Cells(lRow, 686).Value
sMpaa = .Cells(lRow, 687).Value
sPremiered = .Cells(lRow, 688).Value
sReleasedate = .Cells(lRow, 689).Value
sRuntime = .Cells(lRow, 690).Value
sStudio = .Cells(lRow, 691).Value
s1 = .Cells(lRow, 692).Value
s2 = .Cells(lRow, 693).Value
s3 = .Cells(lRow, 694).Value
sFolder = .Cells(lRow, 800).Value
doc.LoadXML sTemplateXML
doc.getElementsByTagName("xml_version")(0).appendChild doc.createTextNode(sXml_version)
doc.getElementsByTagName("xml_movie")(0).appendChild doc.createTextNode(sXml_movie)
doc.getElementsByTagName("plot")(0).appendChild doc.createTextNode(sPlot)
doc.getElementsByTagName("xml_outline")(0).appendChild doc.createTextNode(sXml_outline)
doc.getElementsByTagName("xml_lockdata")(0).appendChild doc.createTextNode(sXml_lockdata)
doc.getElementsByTagName("dateadded")(0).appendChild doc.createTextNode(sDateadded)
doc.getElementsByTagName("title")(0).appendChild doc.createTextNode(sTitle)
doc.getElementsByTagName("rating")(0).appendChild doc.createTextNode(sRating)
doc.getElementsByTagName("year")(0).appendChild doc.createTextNode(sYear)
doc.getElementsByTagName("sorttile")(0).appendChild doc.createTextNode(sSorttile)
doc.getElementsByTagName("mpaa")(0).appendChild doc.createTextNode(sMpaa)
doc.getElementsByTagName("premiered")(0).appendChild doc.createTextNode(sPremiered)
doc.getElementsByTagName("releasedate")(0).appendChild doc.createTextNode(sReleasedate)
doc.getElementsByTagName("runtime")(0).appendChild doc.createTextNode(sRuntime)
doc.getElementsByTagName("studio")(0).appendChild doc.createTextNode(sStudio)
doc.getElementsByTagName("1")(0).appendChild doc.createTextNode(s1)
doc.getElementsByTagName("2")(0).appendChild doc.createTextNode(s2)
doc.getElementsByTagName("3")(0).appendChild doc.createTextNode(s3)
doc.getElementsByTagName("folder")(0).appendChild doc.createTextNode(sFolder)
doc.Save sFile
Next
End With
End Sub
突出显示的错误是“ doc.getElementsByTagName("xml_version")(0).appendChild doc.createTextNode(sXml_version)”
虽然这可能只是第一个顺序。
我想要做的 - 这是针对每一行不为空的
- 创建 XML/文本文件
- 每个文件的内容是行的值 - 每列是一个新行{列的范围,我想由上面的代码概述}
- 文件名 = 第二列值
- folder = 这个excel文件所在目录下的文件夹,与第800列的值同名
- 文件扩展名 = ".NFO"
- 自动/不问我,替换任何现有的同名文件
最后 3 个是斜体字,因为我还没有想到要这样做,因为它不在示例中。例如,我什至不知道将文件夹值放在代码中的哪个位置,它是否可以像我所做的那样与其他列一起列出。我也不知道是否需要模板中的“/data”。
澄清一下,这是为媒体系统自动生成 NFO 文件以作为元数据读取。我有很多面向家庭的视频文件,所以没有元数据网站可以从中抓取数据。
编辑:
更新的代码 - 此代码有效!
Sub Export()
sTemplateXML = _
"<data>" + vbNewLine + _
" <_version/>" + vbNewLine + _
" <_movie/>" + vbNewLine + _
" <plot/>" + vbNewLine + _
" <_outline/>" + vbNewLine + _
" <_lockdata/>" + vbNewLine + _
" <dateadded/>" + vbNewLine + _
" <title/>" + vbNewLine + _
" <rating/>" + vbNewLine + _
" <year/>" + vbNewLine + _
" <sorttile/>" + vbNewLine + _
" <mpaa/>" + vbNewLine + _
" <premiered/>" + vbNewLine + _
" <releasedate/>" + vbNewLine + _
" <runtime/>" + vbNewLine + _
" <studio/>" + vbNewLine + _
" <_1/>" + vbNewLine + _
" <_2/>" + vbNewLine + _
" <_3/>" + vbNewLine + _
"</data>" + vbNewLine
Set doc = CreateObject("MSXML2.DOMDocument")
doc.async = False
doc.validateOnParse = False
doc.resolveExternals = False
With Sheets("Sheet3")
lLastRow = .UsedRange.Rows.Count
For lRow = 3 To lLastRow
sFile = .Cells(lRow, 2).Value
s_version = .Cells(lRow, 677).Value
s_movie = .Cells(lRow, 678).Value
sPlot = .Cells(lRow, 679).Value
s_outline = .Cells(lRow, 680).Value
s_lockdata = .Cells(lRow, 681).Value
sDateadded = .Cells(lRow, 682).Value
sTitle = .Cells(lRow, 683).Value
sRating = .Cells(lRow, 684).Value
sYear = .Cells(lRow, 685).Value
sSorttile = .Cells(lRow, 686).Value
sMpaa = .Cells(lRow, 687).Value
sPremiered = .Cells(lRow, 688).Value
sReleasedate = .Cells(lRow, 689).Value
sRuntime = .Cells(lRow, 690).Value
sStudio = .Cells(lRow, 691).Value
sFolder = .Cells(lRow, 3).Value
s_1 = .Cells(lRow, 692).Value
s_2 = .Cells(lRow, 693).Value
s_3 = .Cells(lRow, 694).Value
doc.LoadXML sTemplateXML
doc.getElementsByTagName("_version")(0).appendChild doc.createTextNode(s_version)
doc.getElementsByTagName("_movie")(0).appendChild doc.createTextNode(s_movie)
doc.getElementsByTagName("plot")(0).appendChild doc.createTextNode(sPlot)
doc.getElementsByTagName("_outline")(0).appendChild doc.createTextNode(s_outline)
doc.getElementsByTagName("_lockdata")(0).appendChild doc.createTextNode(s_lockdata)
doc.getElementsByTagName("dateadded")(0).appendChild doc.createTextNode(sDateadded)
doc.getElementsByTagName("title")(0).appendChild doc.createTextNode(sTitle)
doc.getElementsByTagName("rating")(0).appendChild doc.createTextNode(sRating)
doc.getElementsByTagName("year")(0).appendChild doc.createTextNode(sYear)
doc.getElementsByTagName("sorttile")(0).appendChild doc.createTextNode(sSorttile)
doc.getElementsByTagName("mpaa")(0).appendChild doc.createTextNode(sMpaa)
doc.getElementsByTagName("premiered")(0).appendChild doc.createTextNode(sPremiered)
doc.getElementsByTagName("releasedate")(0).appendChild doc.createTextNode(sReleasedate)
doc.getElementsByTagName("runtime")(0).appendChild doc.createTextNode(sRuntime)
doc.getElementsByTagName("studio")(0).appendChild doc.createTextNode(sStudio)
doc.getElementsByTagName("_1")(0).appendChild doc.createTextNode(s_1)
doc.getElementsByTagName("_2")(0).appendChild doc.createTextNode(s_2)
doc.getElementsByTagName("_3")(0).appendChild doc.createTextNode(s_3)
doc.Save sFolder & sFile & ".NFO"
Next
End With
End Sub
我不确定最后一行,但我只收到 doc.save 并出错,我尝试了所有组合(例如“doc.save sFile”、“doc.save sFile 和“NFO”等)。我已经还尝试了“doc.Save ThisWorkbook.Path & “/” & sFolder & “/” & sFile & “.NFO”。
解决方案
从技术上讲,您应该收到一个错误LoadXML
(除非它返回一个空doc
),因为您的模板 XML 字符串由于各种原因格式不正确:
没有合适的根。你关闭
</data>
但从不在<data>
一开始就打开它。所有节点都不会关闭。尝试添加自闭合标签,您可以稍后在其中附加文本节点。
根据XML 规范规则,节点名称不能以数字开头,也不能以
xml
关键字开头。[定义:名称是具有一组受限初始字符的 Nmtoken。] 名称中不允许使用的初始字符包括数字、变音符号、句号和连字符。
以字符串“xml”开头的名称,或任何与 (('X'|'x') ('M'|'m') ('L'|'l')) 匹配的字符串,都保留用于标准化在本规范的此版本或未来版本中。
考虑使用下划线开头的禁止节点名称进行以下调整:
sTemplateXML = _
"<data>" + vbNewLine + _
" <_xml_version/>" + vbNewLine + _
" <_xml_movie/>" + vbNewLine + _
" <plot/>" + vbNewLine + _
" <xml_outline/>" + vbNewLine + _
" <xml_lockdata/>" + vbNewLine + _
" <dateadded/>" + vbNewLine + _
" <title/>" + vbNewLine + _
" <rating/>" + vbNewLine + _
" <year/>" + vbNewLine + _
" <sorttile/>" + vbNewLine + _
" <mpaa/>" + vbNewLine + _
" <premiered/>" + vbNewLine + _
" <releasedate/>" + vbNewLine + _
" <runtime/>" + vbNewLine + _
" <studio/>" + vbNewLine + _
" <_1/>" + vbNewLine + _
" <_2/>" + vbNewLine + _
" <_3/>" + vbNewLine + _
" <folder/>" + vbNewLine + _
"</data>" + vbNewLine
对于文件名处理,只需在doc.Save
调用中连接需要的部分,这将在没有警告的情况下替换文件。
doc.Save SFolder & "\" & sFile & ".NFO"
推荐阅读
- azure-functions - 在 AuthorizationLevel 设置为“Function”的情况下进行本地测试时,Azure Function 命令行失败
- ruby-on-rails - 即使具有 CanCanCan 功能,也无法访问 Rails 中的操作
- mongodb - MongoDB根据多个条件从数组中选择
- java - 使用 java 8 从列表比较元素中删除
- python - 尝试创建位图时:_tkinter.TclError: bitmap "pyimage2" not defined
- ios - iOS - App Store 是否需要 iPad 屏幕截图才能升级 iPhone 应用程序
- c# - 如何正确实现为异步使用而设计的接口?
- kubernetes - Kubernetes 上的 Istio - 版本兼容性映射
- android - 如何动态更改文件夹名称文件路径 Android Studio?
- r - 如何在 R 中创建嵌套表