Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 如何更改此基于VBA/XSLT的代码,以便将输出写入单个XML文件中_Excel_Xml_Vba_Xslt - Fatal编程技术网

Excel 如何更改此基于VBA/XSLT的代码,以便将输出写入单个XML文件中

Excel 如何更改此基于VBA/XSLT的代码,以便将输出写入单个XML文件中,excel,xml,vba,xslt,Excel,Xml,Vba,Xslt,由于前面的问题,我得到了以下代码 代码的意思是迭代一个excelsheet并用单元格内容自动填充XML标记。输出是此Excel工作表中每一行的XML文件 现在,我有一个非常类似的案例,我知道,要完成它,改变不多。我希望我的代码不是为每一行创建一个新的XML文件,而是在同一个XML文件中填充所有内容 我想自动填写此excel表格的内容: 转换为一个XML模板,该模板最初如下所示: <?xml version="1.0" encoding="UTF-8"?> <Codes>

由于前面的问题,我得到了以下代码

代码的意思是迭代一个excelsheet并用单元格内容自动填充XML标记。输出是此Excel工作表中每一行的XML文件

现在,我有一个非常类似的案例,我知道,要完成它,改变不多。我希望我的代码不是为每一行创建一个新的XML文件,而是在同一个XML文件中填充所有内容

我想自动填写此excel表格的内容:

转换为一个XML模板,该模板最初如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Codes>
<AreaCodes>
<Area>
<Name></Name>
<Desc/>
<Facility_Area></Facility_Area>
</Area>
</AreaCodes>
</Codes>
<?xml version="1.0" encoding="UTF-8"?>
<Codes>
<AreaCodes>
<Area>
<Name>RA 001</Name>
<Desc/>
<Facility_Area>ZUF</Facility_Area>
</Area>
<Area>
<Name>RA 002</Name>
<Desc/>
<Facility_Area>ZUF</Facility_Area>
</Area>
<Area>
<Name>RA 003</Name>
<Desc/>
<Facility_Area>ZUF</Facility_Area>
</Area>
<Area>
<Name>RA 004</Name>
<Desc/>
<Facility_Area>ZUF</Facility_Area>
</Area>
...
</AreaCodes>
</Codes>
现在,所有内容都放在一个单独的XML文件中

谁能告诉我,我要改变什么?我知道,对于我的VBA代码,我应该将那些save命令移到循环之外,但这不起作用


很抱歉在英语方面遇到了困难,谢谢大家的帮助。

我编写了一个VBA类模块
SheetWrapper

Private mySheet As Object

Sub Init(sheet)
    Set mySheet = sheet
End Sub

Public Property Get Cell(rowIndex, cellIndex)
    Cell = CStr(mySheet.Cells(rowIndex, cellIndex).Value)
End Property
这样就可以使用

Sub Param_XSLT_Process()
    Dim xmlDoc As New MSXML2.DOMDocument60

    Dim xslDoc As New MSXML2.FreeThreadedDOMDocument60

    Dim xslTemp As New MSXML2.XSLTemplate60

    Dim xslProc As MSXML2.IXSLProcessor

    Dim resultDoc As New MSXML2.DOMDocument60

    Dim worksheet As Object
    Set worksheet = ActiveWorkbook.Worksheets(1)

    Dim myWrapper As SheetWrapper
    Set myWrapper = New SheetWrapper

    myWrapper.Init worksheet


    ' LOAD XML AND XSL FILES
    xmlDoc.async = False
    xmlDoc.Load "C:\SomePath\template.xml"

    xslDoc.async = False
    xslDoc.SetProperty "AllowDocumentFunction", True
    xslDoc.Load "C:\SomePath\sheet.xsl"

    ' INITIALIZE NEEDED OBJECTS
    Set xslTemp.stylesheet = xslDoc
    Set xslProc = xslTemp.createProcessor()

    xslProc.addObject myWrapper, "http://example.com/excel"

    xslProc.addParameter "first-row-index", 2, ""
    xslProc.addParameter "last-row-index", ActiveWorkbook.Worksheets(1).UsedRange.Rows.Count, ""


    xslProc.input = xmlDoc

    xslProc.output = resultDoc

    xslProc.transform

    resultDoc.Save "C:\SomePath\transformation-result.xml"
End Sub
与XSLT一起:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:excel="http://example.com/excel"
    exclude-result-prefixes="msxsl excel">

    <xsl:param name="sheet"/>

    <xsl:param name="first-row-index"/>
    <xsl:param name="last-row-index"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:output indent="yes"/>

    <xsl:template match="AreaCodes">
        <xsl:copy>
            <xsl:call-template name="make-areas">
                <xsl:with-param name="area" select="Area"/>
                <xsl:with-param name="index" select="$first-row-index"/>
                <xsl:with-param name="last" select="$last-row-index"/>
            </xsl:call-template>
        </xsl:copy>
    </xsl:template>

    <xsl:template name="make-areas">
        <xsl:param name="area"/>
        <xsl:param name="index"/>
        <xsl:param name="last"/>
        <xsl:apply-templates select="$area">
            <xsl:with-param name="row-index" select="$index"/>
        </xsl:apply-templates>
        <xsl:if test="$index &lt; $last">
            <xsl:call-template name="make-areas">
                <xsl:with-param name="area" select="$area"/>
                <xsl:with-param name="index" select="$index + 1"/>
                <xsl:with-param name="last" select="$last"/>
            </xsl:call-template>            
        </xsl:if>
    </xsl:template>

    <xsl:template match="Area">
        <xsl:param name="row-index"/>
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:with-param name="row-index" select="$row-index"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Area/Name">
        <xsl:param name="row-index"/>
        <xsl:copy>
            <xsl:value-of select="excel:get-Cell($row-index, 1)"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Area/Facility_Area">
        <xsl:param name="row-index"/>
        <xsl:copy>
            <xsl:value-of select="excel:get-Cell($row-index, 2)"/>
        </xsl:copy>
    </xsl:template>    

</xsl:stylesheet>


我本来希望能够将Excel sheet对象直接传递给XSLT以读取其单元格,但MSXML却没有做到这一点。

我将在周一尝试,并给出我的反馈。多谢各位!
Sub Param_XSLT_Process()
    Dim xmlDoc As New MSXML2.DOMDocument60

    Dim xslDoc As New MSXML2.FreeThreadedDOMDocument60

    Dim xslTemp As New MSXML2.XSLTemplate60

    Dim xslProc As MSXML2.IXSLProcessor

    Dim resultDoc As New MSXML2.DOMDocument60

    Dim worksheet As Object
    Set worksheet = ActiveWorkbook.Worksheets(1)

    Dim myWrapper As SheetWrapper
    Set myWrapper = New SheetWrapper

    myWrapper.Init worksheet


    ' LOAD XML AND XSL FILES
    xmlDoc.async = False
    xmlDoc.Load "C:\SomePath\template.xml"

    xslDoc.async = False
    xslDoc.SetProperty "AllowDocumentFunction", True
    xslDoc.Load "C:\SomePath\sheet.xsl"

    ' INITIALIZE NEEDED OBJECTS
    Set xslTemp.stylesheet = xslDoc
    Set xslProc = xslTemp.createProcessor()

    xslProc.addObject myWrapper, "http://example.com/excel"

    xslProc.addParameter "first-row-index", 2, ""
    xslProc.addParameter "last-row-index", ActiveWorkbook.Worksheets(1).UsedRange.Rows.Count, ""


    xslProc.input = xmlDoc

    xslProc.output = resultDoc

    xslProc.transform

    resultDoc.Save "C:\SomePath\transformation-result.xml"
End Sub
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:excel="http://example.com/excel"
    exclude-result-prefixes="msxsl excel">

    <xsl:param name="sheet"/>

    <xsl:param name="first-row-index"/>
    <xsl:param name="last-row-index"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:output indent="yes"/>

    <xsl:template match="AreaCodes">
        <xsl:copy>
            <xsl:call-template name="make-areas">
                <xsl:with-param name="area" select="Area"/>
                <xsl:with-param name="index" select="$first-row-index"/>
                <xsl:with-param name="last" select="$last-row-index"/>
            </xsl:call-template>
        </xsl:copy>
    </xsl:template>

    <xsl:template name="make-areas">
        <xsl:param name="area"/>
        <xsl:param name="index"/>
        <xsl:param name="last"/>
        <xsl:apply-templates select="$area">
            <xsl:with-param name="row-index" select="$index"/>
        </xsl:apply-templates>
        <xsl:if test="$index &lt; $last">
            <xsl:call-template name="make-areas">
                <xsl:with-param name="area" select="$area"/>
                <xsl:with-param name="index" select="$index + 1"/>
                <xsl:with-param name="last" select="$last"/>
            </xsl:call-template>            
        </xsl:if>
    </xsl:template>

    <xsl:template match="Area">
        <xsl:param name="row-index"/>
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:with-param name="row-index" select="$row-index"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Area/Name">
        <xsl:param name="row-index"/>
        <xsl:copy>
            <xsl:value-of select="excel:get-Cell($row-index, 1)"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Area/Facility_Area">
        <xsl:param name="row-index"/>
        <xsl:copy>
            <xsl:value-of select="excel:get-Cell($row-index, 2)"/>
        </xsl:copy>
    </xsl:template>    

</xsl:stylesheet>