Excel“从xml数据导入”不会添加新列

时间:2013-11-04 14:37:29

标签: xml excel vba excel-vba xslt

Excel 2010在Data->“From Other Sources” - >“From XML Data Import”下有一个很棒的功能,可以从Web服务中提取XML,无需编码。效果很好,但我的服务现在最后添加了一个新列。刷新Excel中的连接不会添加新列。实际上,在同一电子表格中创建与完全相同的URL的第二个连接也不会显示新列(尽管在不同的Excel工作簿上执行相同的操作)。显然,Excel正以某种方式缓存列。

我发现this link通过手动黑客攻击excel文件来描述可能的解决方法;但那是3年前的事了。当然,现在有更好的方法。

有什么建议吗?您可以通过将以下XML保存为文本文件,将其导入Excel,然后编辑文件并添加新列来复制此操作。

<Table>
    <Row>
        <First>1</First>
        <Second>2</Second>
    </Row>
    <Row>
        <First>3</First>
        <Second>4</Second>
    </Row>
</Table>

2 个答案:

答案 0 :(得分:4)

选项:

我没有尝试过链接论坛帖子中的VBA代码,如下所示。我希望这个对你有用。但是,对于引用映射内部数据的公式,下面的解决方法似乎很容易且无中断。因此,我会使用它,除非它不适合您或者您的映射很复杂,或者您希望需要多次半自动更新(尽管下面的解决方法只花费很少的时间)。

似乎没有Excel 2007的官方解决方案。似乎有两个单独的官方解决方案:一个用于Excel 2003(附加组件),另一个用于Excel 2010(开发人员选项卡)。

问题Excel Add A Field To An Xml Map提供了三种可行的方法。

  • 第一个是XML Toolbox for Excel 2003可以做到这一点 在Excel 2003中。对该解决方案的评论表明它有一些 问题/问题,可能会或可能不会对您有用。你可以 必须在Excel上使用旧版本,甚至是旧操作版本 系统。
  • 第二个是&#34;编辑.xls文件&#34;方法
  • 第三种方法是使用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>

解决方法:[添加/插入/删除列](简单映射很容易,例如一个大表):

  1. 制作工作表的备份副本。
  2. 删除 XML地图不是工作表中的映射。只是XML地图。
  3. 重新创建地图。它现在将具有新的XML架构。
  4. 如果您的公式/数据会被其他列覆盖:在包含XML映射数据的工作表的当前区域的右侧立即插入足够的列。
  5. 如果在旧列之间有插入的列,则在工作表中插入一列它们将会到达的列。是的,这在XML映射数据区域中是正确的,并且将临时分配通用列名称。
  6. 删除新XML中不存在的任何列。
  7. 将新映射表格中的元素拖放到当前映射的左上角(或以其他方式直接在尚未删除的映射上重新创建工作表上的映射)
  8. 手动更改已更新的所有标题(如果您的数据标记为标题)。
  9. 对工作簿中的所有单独映射重复步骤4到8。通常我只有一个大的映射,我引用它而不是多个小映射。
  10. 刷新XML数据。
  11. 您的公式不应该更改,并且对XML映射数据的单元格引用应保持正确。为了验证您是否正确插入了步骤3中的任何列,您可以在进行任何其他更改之前(即在步骤1a)在XML映射上方创建一行,并仅复制并粘贴顶行中的值。在步骤10中刷新XML数据时,您可以验证旧行标题是否与新位置匹配。

    注意:可以通过对XML元素进行更复杂的映射来替代地完成步骤3和4。我发现插入列并与XMl元素保持1-1对应更容易。

    这可以通过多次试验在我的机器上工作,并使公式引用该区域为正确。您可以进行实验的文件称为SO-XML mapping.xml,它包含在下面链接的示例文件中(and here

    考虑从源获取的某些数据表中的通用列更改(或可互换地使用多个源):

    有些情况下,您所拥有的数据不是由XML地图等动态提供的,或者您不想在记住插入列时遇到困难。实现此目的的强制解决方法是创建您自己的数据列映射到工作表中的表(表),您可以在其中控制列位置。您可以通过创建一个表来间接引用已导入/复制到其他工作表中的数据来执行此操作。使用这样的间接映射也可以用来轻松地在两个或更多个不同的数据集之间切换,作为您设置的任何公式的输入。

    间接映射使用INDIRECT()来引用包含源数据的工作表。然后,所有公式都指向此间接工作表而不是源数据。间接工作表中列的内容组织在固定位置,数据从源数据中与指定列标题匹配的列中提取。然后,如果对源数据中的列的组织进行了更改,则可以使用交替格式化的数据创建新工作表,或者将其放在原始数据所在的工作表中,并更改列标题。用于参考。如果在多个数据集之间切换,则可以通过更改一个单元格来完全更改使用的源数据。

    此间接映射表允许修复公式中的列(在间接工作表之外),而不必担心可能的源数据重组。或者,它允许您拥有两个或更多数据集,当您在它们之间切换时,这些数据集会自动转换为相同的列组织。即使数据集具有用于相同实际数据的不同标头,也可以实现此目的(只有在选择了备用数据集时使用的标题行)。

    这可能比在这样的帖子中解释更容易。因此,这是一个example which selects data from five different sheets

    在该示例中,您的所有公式都将引用“间接”页面。该示例假定所有文件都放在C:\目录中。不幸的是,使用XML映射需要一个完整的文件路径,C:\是运行Excel的大多数机器上存在的概率最高的位置。

    2009年11月16日来自KMKfan的VBA代码:

    张贴于XML Question - Update Schema/Mappingarchive)(archive of the Programatically using XML Mapping Feature page that post references)。

    帖子中的评论是:

      

    以下是此代码的更新。此代码允许多个XML   只要xsd和xml映射,映射就可以在同一工作簿中更新   具有相同的名称(即:源地图&#34; MyMap&#34;基于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
    

答案 1 :(得分:0)

试试这个:

突出显示导入的数据,并删除他们填充的行。然后,选择要插入数据的单元格,并通过转到数据重新创建连接 - &gt;来自XML数据导入。重新创建连接时,应添加额外的列。 (如果您尝试刷新当前存在的数据表,则不会附加您的列。)