使用 VBA 创建 Word 或 XML 文档

发布于 2024-07-13 19:12:12 字数 1531 浏览 2 评论 0原文

我需要在 Word 2003 中使用 VBA 创建文档(约 150 份报告、信件),主要来自预先存在的片段和本地数据库。然后,我需要更改这些片段的特定部分,例如日期、短语、用户信息, &c。 显然,我还将在程序中生成一些位。

目前,同样的任务(在某种程度上)是由一些可怕的遗留 VBA 完成的。 (嵌套的 IF 和 FOR,以及超过 200 个文本框,全部称为 TextBox#)它有时可以完成工作,并通过向 Word 应用程序发送指令来完成此任务(Selection.MoveDown Unit:wdLine, Count:=1 例如。)因此,即使生成一封简单的信件也需要 30 秒,并且会锁定 Office。

我完全能够使用范围和书签以及改进的逻辑做同样的事情,但我的直觉是,使用 XML 应该很容易做到这一点,并且这样做在将来会有优势,因为这些报告/信件是被许多不同的用户和应用程序多次访问并可能以编程方式读取。

我一直在阅读有关 XML 和 WordML 架构的内容,但感觉我错过了一些东西。

我希望代码在提交时执行以下操作:

  1. 获取预定义的 xml 片段(页眉、页脚等)
  2. 生成新字符串并连接预定义的 XML 字符串
  3. 另存为 XML
  4. 更改 XML 文件中现有标记的值(日期、用户名等)

我可以做这个。

我遇到的问题是:

  • 我在理解模式和命名空间方面遇到了困难。 数据已通过 VBA 代码验证,那么我需要架构做什么?

  • 最好是通过创建一个包含整个文档的 XML 的长连接字符串来创建文档(请记住,在我的模型中,大部分 XML 将来自现有片段),还是使用 XML Dom 并以编程方式创建它:

20 Set oElementName = oDOM.createElement("Name")

30 oElement.appendChild oElementName

40 oElementName.Text = "This is the text of name"

  • 我如何设计文档的样式? (从概念上讲,这给我带来了最大的麻烦。)我并不特别想从 Word 保存时生成的 WordML 对其进行逆向工程。 我想我需要先将其转换为 HTML? 我可以在 Word 中创建样式表以便自动设置格式吗?

这些有道理吗? 我应该只使用范围和书签吗?

XML 对我来说似乎很强大,但它可能是锤子和钉子问题的扭曲情况,即“我想学习 Hammer,所以每个问题看起来都像钉子,这给了我学习 Hammer 的充分理由”。

(我知道我不应该像我一样学习如何做事!但我只是一个无意识的无人机,对我们的文档生成系统的质量抱怨够多,以至于他们说“闭嘴,然后修复它!哦,你不懂 VBA 吗?好吧,我们没钱送你去学习任何课程,所以边学边学吧。”这是我工作生涯中最好和最差的两个月。)

我感谢你阅读全文所有这些,如果你这样做了,以及你可能有的任何帮助/建议!

I need to create documents, (~150 reports, letters) mostly from pre-existing snippets and local databases, with VBA, in Word 2003. I then need to change specific parts of those snippets, such as dates, phrases, user information, &c. There are also, obviously, some bits that I will generate in my program.

Currently, this same task is done (sort of) by some hideous legacy VBA. (Nested IFs and FORs, and over 200 textboxes all called TextBox#) It gets the job done SOMETIMES, and does so by sending instructions to the Word application (Selection.MoveDown Unit:wdLine, Count:=1, for example.) Consequently, generating even a simple letter takes 30 seconds, and locks up Office.

I'm perfectly able to do the same thing with ranges and bookmarks and improved logic, but my gut feeling is that this should be easy to do this with XML and that doing so will have advantages in the future, as these reports/letters are to be accessed, and likely read programmatically, many times by many different users and applications.

I have been reading about XML and the WordML schema, but feel like I'm missing something.

What I want the code to do on Submit is this:

  1. Grab predefined xml snippets (header, footer, etc.)
  2. Generate new strings and concatenate predefined XML strings
  3. Save as XML
  4. Change value of existing tags in XML file (date, username, etc)

I can do this.

The issues I have are:

  • I been having trouble getting my head around schema and namespaces. The data is already validated by the VBA code, so what do I need a schema for?

  • Is it better to create the document by creating one long concatenated string containing the XML for the entire document, bearing in mind in my model much of the XML would be from existing snippets, or to use the XML Dom and create it programmatically:

20 Set oElementName = oDOM.createElement("Name")

30 oElement.appendChild oElementName

40 oElementName.Text = "This is the text of name"

  • HOW DO I STYLE THE DOCUMENT? (This has been causing me the most trouble, conceptually.) I don't particularly want to reverse engineer it from the WordML that Word generates when it saves. I take it I need to convert it to HTML first? Can I create a stylesheet in Word so it automatically formats it?

Does any of this make sense? Should I just use ranges and bookmarks instead?

XML seems powerful to me, but it could be a twisted case of the hammer and nail problem, i.e. "I want to learn Hammer, so every problem looks like a nail, giving me a good reason to learn Hammer."

(I know I shouldn't be learning how to do things as I do them! But I'm just a mindless drone who complained enough about the quality of our document generation system that they said "Shut up and fix it then! Oh, you don't know any VBA? Well, we can't afford to send you on a course or anything, so learn as you go." It's been the best and worst 2 months of my working life.)

I appreciate you reading through all of that, if you did, and any help/advice you might have!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

汹涌人海 2024-07-20 19:12:12

我不知道您的任务情况,也许有充分的理由继续您的技术堆栈,但似乎应该重新考虑对 Office 2003 的如此大的投资(150 份报告是很大的)。
虽然 Microsoft 表示 VBA 不会消失,但我认为 Open XML SDK 拥有更光明的未来。

这是 XML 标记的精彩介绍

I don't know the circumstances of your assignment and there may be good reasons to move ahead with your technology stack, but it seems that such a big investment (150 reports is big) into Office 2003 should be reconsidered.
While Microsoft is saying that VBA will not go away, I think that the Open XML SDK has a brighter future.

Here is an excellent introduction into the XML markup.

神经暖 2024-07-20 19:12:12

好的,我已经找到了样式部分问题的答案。 (我总是在提交问题后不久就发现这些东西!)

读完这篇文章对我来说更有意义!

来自:http://www.tkachenko.com/blog/archives/000024.html< /a>

<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<chapter title="XSLT Programming">
    <para>It's <i>very</i> simple. Just ask <link
url="http://google.com">Google</link>.</para>
</chapter>

然后是 XSLT 样式表(由于基于详细元素的 WordML 语法,该样式表相当大):

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="http://schemas.microsoft.com/office/word/2003/2/wordml">
    <xsl:template match="/">
        <xsl:processing-instruction 
name="mso-application">progid="Word.Document"</xsl:processing-instruction>
        <w:wordDocument>
            <xsl:apply-templates/>
        </w:wordDocument>
    </xsl:template>
    <xsl:template match="chapter">
        <o:DocumentProperties>
            <o:Title>
                <xsl:value-of select="@title"/>
            </o:Title>
        </o:DocumentProperties>
        <w:styles>
            <w:style w:type="paragraph" w:styleId="Heading3">
                <w:name w:val="heading 3"/>
                <w:pPr>
                    <w:pStyle w:val="Heading3"/>
                    <w:keepNext/>
                    <w:spacing w:before="240" w:after="60"/>
                    <w:outlineLvl w:val="2"/>
                </w:pPr>
                <w:rPr>
                    <w:rFonts w:ascii="Arial" w:h-ansi="Arial"/>
                    <w:b/>
                    <w:sz w:val="26"/>
                </w:rPr>
            </w:style>
            <w:style w:type="character" w:styleId="Hyperlink">
                <w:rPr>
                    <w:color w:val="0000FF"/>
                    <w:u w:val="single"/>
                </w:rPr>
            </w:style>
        </w:styles>
        <w:body>
            <w:p>
                <w:pPr>
                    <w:pStyle w:val="Heading3"/>
                </w:pPr>
                <w:r>
                    <w:t>
                        <xsl:value-of select="@title"/>
                    </w:t>
                </w:r>
            </w:p>
            <xsl:apply-templates/>
        </w:body>
    </xsl:template>
    <xsl:template match="para">
        <w:p>
            <xsl:apply-templates/>
        </w:p>
    </xsl:template>
    <xsl:template match="i">
        <w:r>
            <w:rPr>
                <w:i/>
            </w:rPr>
            <xsl:apply-templates/>
        </w:r>
    </xsl:template>
    <xsl:template match="text()">
        <w:r>
            <w:t xml:space="preserve"><xsl:value-of 
select="."/></w:t>
        </w:r>
    </xsl:template>
    <xsl:template match="link">
        <w:hlink w:dest="{@url}">
            <w:r>
                <w:rPr>
                    <w:rStyle w:val="Hyperlink"/>
                    <w:i/>
                </w:rPr>
                <xsl:apply-templates/>
            </w:r>
        </w:hlink>
    </xsl:template>
</xsl:stylesheet>

Okay, so I've found an answer to the styling part of my problems. (I always find these things shortly after I submit questions!)

And having read this it makes MUCH more sense to me!

From: http://www.tkachenko.com/blog/archives/000024.html

<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<chapter title="XSLT Programming">
    <para>It's <i>very</i> simple. Just ask <link
url="http://google.com">Google</link>.</para>
</chapter>

Then XSLT stylesheet (quite big one due to verbose element-based WordML syntax):

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="http://schemas.microsoft.com/office/word/2003/2/wordml">
    <xsl:template match="/">
        <xsl:processing-instruction 
name="mso-application">progid="Word.Document"</xsl:processing-instruction>
        <w:wordDocument>
            <xsl:apply-templates/>
        </w:wordDocument>
    </xsl:template>
    <xsl:template match="chapter">
        <o:DocumentProperties>
            <o:Title>
                <xsl:value-of select="@title"/>
            </o:Title>
        </o:DocumentProperties>
        <w:styles>
            <w:style w:type="paragraph" w:styleId="Heading3">
                <w:name w:val="heading 3"/>
                <w:pPr>
                    <w:pStyle w:val="Heading3"/>
                    <w:keepNext/>
                    <w:spacing w:before="240" w:after="60"/>
                    <w:outlineLvl w:val="2"/>
                </w:pPr>
                <w:rPr>
                    <w:rFonts w:ascii="Arial" w:h-ansi="Arial"/>
                    <w:b/>
                    <w:sz w:val="26"/>
                </w:rPr>
            </w:style>
            <w:style w:type="character" w:styleId="Hyperlink">
                <w:rPr>
                    <w:color w:val="0000FF"/>
                    <w:u w:val="single"/>
                </w:rPr>
            </w:style>
        </w:styles>
        <w:body>
            <w:p>
                <w:pPr>
                    <w:pStyle w:val="Heading3"/>
                </w:pPr>
                <w:r>
                    <w:t>
                        <xsl:value-of select="@title"/>
                    </w:t>
                </w:r>
            </w:p>
            <xsl:apply-templates/>
        </w:body>
    </xsl:template>
    <xsl:template match="para">
        <w:p>
            <xsl:apply-templates/>
        </w:p>
    </xsl:template>
    <xsl:template match="i">
        <w:r>
            <w:rPr>
                <w:i/>
            </w:rPr>
            <xsl:apply-templates/>
        </w:r>
    </xsl:template>
    <xsl:template match="text()">
        <w:r>
            <w:t xml:space="preserve"><xsl:value-of 
select="."/></w:t>
        </w:r>
    </xsl:template>
    <xsl:template match="link">
        <w:hlink w:dest="{@url}">
            <w:r>
                <w:rPr>
                    <w:rStyle w:val="Hyperlink"/>
                    <w:i/>
                </w:rPr>
                <xsl:apply-templates/>
            </w:r>
        </w:hlink>
    </xsl:template>
</xsl:stylesheet>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文