选项:
我还没有尝试过链接论坛帖子中的 VBA 代码并包含在下面。我希望这个对你有用。但是,下面的解决方法似乎很简单,并且不会对引用映射内数据的公式造成干扰。因此,我会使用它,除非它对您不起作用或者您的映射很复杂,或者您希望需要多次半自动更新(尽管下面的解决方法需要很少的时间)。
Excel 2007 似乎没有官方解决方案。似乎有两种单独的官方解决方案:一种用于 Excel 2003(附加组件),另一种用于 Excel 2010(开发人员选项卡)。
Excel Add A Field To An Xml Map问题提供了三种可能有效的方法。
- 第一个是 Excel 2003 的XML 工具箱,它可以在 Excel 2003 中执行此操作。对该解决方案的评论表明它存在一些问题/问题,可能对您有用,也可能不适用。您可能必须在 Excel 上使用旧版本,甚至是旧操作系统。
- 第二个是“编辑 .xls 文件”方法。
- 第三个是使用 Excel 2010 Developer 选项卡。
附加选项:
- 下面提供了解决方法(可能我选择了简单的一次性更新,预计不会重复并且映射很简单)。
- 将工作表另存为 XML 电子表格。编辑文件末尾记录的模式。鉴于它是 XML,它完全是文本。架构很容易理解。添加列就像复制和粘贴(修改)几行 XML 文本一样简单。如果使用此方法,最简单的方法可能是复制工作表,删除并重新创建地图和映射,然后剪切和粘贴。示例 XML:
(SO 格式需要空白文本)
<x2:Field x2:ID="Add-E-head">
<x2:Range>RC[4]</x2:Range>
<x2:XPath>Add-E-head</x2:XPath>
<x2:XSDType>string</x2:XSDType>
<ss:Cell>
</ss:Cell>
<x2:Aggregate>None</x2:Aggregate>
</x2:Field>
解决方法:[添加/插入/删除列](易于简单映射,例如一张大表):
- 制作工作表的备份副本。
- 删除XML 映射。不是工作表中的映射。只是 XML 映射。
- 重新创建地图。它现在将具有新的 XML 模式。
- 如果您有将被其他列覆盖的公式/数据: 在包含 XML 映射数据的工作表上的当前区域的右侧插入足够的列。
- 如果在旧列之间插入了任何列,则在工作表中插入一列它们将去的地方。是的,这正好在 XML 映射数据区域中,并且将临时分配通用列名。
- 删除新 XML 中不存在的所有列。
- 将新映射表中的元素拖放到当前映射的左上角(或者直接在未删除的映射上重新创建工作表上的映射)。
- 手动更改任何已更新的标题(如果您的数据被标记为具有标题)。
- 对工作簿中的所有单独映射重复步骤 4 到 8。通常我只有一个大映射,而不是多个小映射。
- 刷新您的 XML 数据。
您的公式不应更改,对 XML 映射数据的单元格引用应保持正确。为了验证您在步骤 3 中是否正确插入了任何列,您可以在进行任何其他更改之前(即在步骤 1a 中)在 XML 映射上方创建一行,然后仅复制和粘贴顶行中的值。在步骤 10 中刷新 XML 数据时,您可以验证旧行标题是否与新位置匹配。
注意:步骤 3 和 4 可以通过对 XML 元素进行更复杂的映射来交替完成。我发现只插入列并与 XMl 元素保持 1-1 对应更容易。
这在我的机器上通过了多次试验,并让引用该区域的公式保持正确。您可以在其中进行试验的文件 SO-XML mapping.xml 包含在下面链接的示例文件中(和此处)
考虑从某个源(或交替使用多个源)获得的某些数据表中的通用列更改:
有时,您拥有的数据不是由 XML 映射之类的东西动态提供的,或者您不想为记住插入的列而烦恼。实现此目的的蛮力解决方法是创建您自己的数据列映射到您控制列位置的工作表中的表(工作表)。您可以通过创建一个间接引用您已导入/复制到不同工作表中的数据的表来执行此操作。使用这样的间接映射也可用于在两个或多个不同的数据集之间轻松切换,作为您设置的任何公式的输入。
间接映射用于INDIRECT()
引用包含源数据的工作表。然后,您的所有公式都指向此间接工作表而不是源数据。间接工作表中列的内容组织在固定位置,其中数据从源数据中与指定列标题匹配的列中提取。然后,如果对源数据中列的组织进行了更改,您可以使用交替格式化的数据创建一个新工作表,或者将其放置在原始数据所在的工作表中并更改您所在的列标题用于参考。如果在多个数据集之间切换,则可以通过更改一个单元格来完全更改使用的源数据。
此间接映射表允许固定公式中的列(在间接表之外),而不必担心可能对源数据进行重组。或者,它允许您拥有两个或更多数据集,当您在它们之间切换时,它们会自动转换为相同的列组织。即使数据集具有用于相同实际数据的不同标题,您也可以完成此操作(只有在选择备用数据集时使用的标题行)。
这可能比在这样的帖子中解释更容易。因此,这是一个从五个不同工作表中选择数据的示例。
在该示例中,您的所有公式都将引用间接页面。该示例假定所有文件都放在C:\
目录中。不幸的是,使用 XML 映射需要完整的文件路径,并且C:\
是大多数运行 Excel 的机器上存在的最高概率位置。
2009 年 11 月 16 日来自KMKfan的VBA 代码:
张贴在XML 问题 - 更新架构/映射(存档)(以编程方式使用 XML 映射功能页面发布参考的存档)。
帖子中的评论是:
这是此代码的更新。此代码允许在同一个工作簿中更新多个 XML 映射,只要 xsd 和 xml 映射具有相同的名称(即:源映射“MyMap”基于 MyMap.xsd。如果您使用 XML,应该非常有用协助报告并决定添加一条数据进行捕获。您可以自动更新现有映射,只需手动更新新数据元素。
Dim r, c As Integer
Dim wb1, wb2 As Workbook
Dim StrMap, StrWS, StrRng, StrXPath As String
Dim nStrWS, nStrRng, nStrXPath As String
Dim nStrMap As XmlMap
Sub Update_XML()
Call Get_XPath
Call Add_NewMap
Call Assign_Elements
End Sub
Sub Get_XPath()
'Gets Available XML Mappings (XPath) for current workbook and sends the text information to a temp file.
Set wb1 = ThisWorkbook
Set wb2 = Workbooks.Add
wb1.Activate
For Each Sheet In wb1.Sheets
Sheet.Select
Range("A1").Select
Selection.UnMerge
For c = 1 To ActiveSheet.UsedRange.Columns.Count
For r = 1 To ActiveSheet.UsedRange.Rows.Count
If ActiveCell.Offset(r - 1, c - 1).XPath <> "" Then Call Send_XPath
wb1.Activate
Next r
Next c
Selection.Merge
Next Sheet
End Sub
Sub Send_XPath()
'Sends text information to a temporary workbook for use later.
StrWS = ActiveSheet.Name
StrRng = ActiveCell.Offset(r - 1, c - 1).Address
StrXPath = ActiveCell.Offset(r - 1, c - 1).XPath
StrMap = ActiveCell.Offset(r - 1, c - 1).XPath.Map.Name
With wb2
.Activate
ActiveCell = StrMap
ActiveCell.Offset(0, 1) = StrWS
ActiveCell.Offset(0, 2) = StrRng
ActiveCell.Offset(0, 3) = StrXPath
ActiveCell.Offset(1, 0).Select
End With
End Sub
Sub Add_NewMap()
'Delete the current XML map and add a new XML Map that has the same schema structure.
'XML Map and XSD schema must be named identically. Only the .xsd extension should be different.
Dim MyPath, MyMap As String
MyPath = 'Path of .xsd file goes here
For Each XmlMap In wb1.XmlMaps
MyMap = XmlMap.Name
wb1.XmlMaps(XmlMap.Name).Delete
wb1.XmlMaps.Add(MyPath & "\" & MyMap & ".xsd").Name = MyMap
Next XmlMap
End Sub
Sub Assign_Elements()
'Assign XPath of new XML Map to ranges based on the information in the temp workbook. Close 2nd workbook w/o saving.
With wb2
.Activate
Application.Goto Range("$A$1")
End With
Do Until ActiveCell = ""
Set nStrMap = wb1.XmlMaps(ActiveCell.Text)
nStrWS = ActiveCell.Offset(0, 1)
nStrRng = ActiveCell.Offset(0, 2)
nStrXPath = ActiveCell.Offset(0, 3)
With wb1
.Activate
Sheets(nStrWS).Select
Range(nStrRng).XPath.SetValue nStrMap, nStrXPath
End With
wb2.Activate
ActiveCell.Offset(1, 0).Select
Loop
wb2.Close False
End Sub