- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 Excel 中有一个 VBA 脚本,它在 MS Word 中生成一个简单的报告。它遍历一个二维数组,并将每一行打印为一条线(带有一些转换和检查)。
我的问题是:每行以 2 个制表符开头,每当一行太长而无法容纳时,它就会换到下一行。这个新行从页面的开头开始,但是,我需要与上一行对齐并从 2 个选项卡开始。
这是代码:
Sub Macro()
Dim i As Long
Dim szLine As String
szLine = "EXAMPLE STRING DATA, EXAMPLE STRING DATA, EXAMPLE STRING DATA, EXAMPLE STRING DATA"
'Header information
Selection.TypeText Text:="1. PARA 1"
Selection.TypeText Text:=vbCrLf
Selection.TypeText Text:=vbTab & "(a) SUB PARA"
Selection.TypeText Text:=vbCrLf
For i = 1 To 5
'Create String Line to Print
szLine = "EXAMPLE STRING DATA, EXAMPLE STRING DATA, EXAMPLE STRING DATA, EXAMPLE STRING DATA"
szLine = vbTab & vbTab & i & "." & vbTab & szLine
'Print
Selection.TypeText Text:=szLine
Selection.TypeText Text:=vbCrLf
Next i
End Sub
Here is an image showing an example of the document as is.
Public Function FixTabs(sz As String) As String
FixTabs = "NULL"
Dim numTabs As Long
Dim numSplit As Long
Dim sepSplit As String
Dim szReturn As String
Dim i As Long
Dim j As Long
Dim hasSplit As Boolean
Dim charLimit As Long
numTabs = 2
numSplit = 3
sepSplit = ","
'Determined by trial and error. Tabs are 5 chars long-ish
charLimit = (numTabs * 5) + 10
'Return the string as is if its not too big
If LenB(sz) < charLimit Then
MsgBox LenB(sz)
FixTabs = sz
Exit Function
End If
'Otherwise iterate through, and split the line by the sep char.
hasSplit = False
szReturn = ""
j = 0
For i = 1 To LenB(sz)
'Build the return string
szReturn = szReturn & Mid(sz, i, 1)
If Mid(sz, i, 1) = sepSplit Then
'Seperator found
j = j + 1
Else
'Check when to insert the new line
If j >= numSplit And hasSplit = False Then
hasSplit = True 'Only do this once.
szReturn = szReturn & vbCrLf & vbTab & vbTab 'Add newline and more tabs
End If
End If
Next i
FixTabs = szReturn
End Function
如您所见,这不太理想。它仅在 90% 的时间内有效,因为实际数据不太一致,字符并不总是相同。
.Paragraphs.LeftIndent = 72
是我最终使用的。不完美,但似乎正是我所需要的是不可能的。
最佳答案
您确实需要花一些时间学习 Word 工作原理的基础知识。使用选项卡等蛮力布局是非常糟糕的做法。
学习使用段落缩进(第一行,悬挂,左右)而不是制表符,更好的是段落样式 - 因为与 Word 中的段落格式有关的一切都基于段落样式。
此外,您需要学习使用 Word 模板。使用模板,您的所有样板文本、基本格式和段落样式都可以就位,因此您只需在相关位置插入相应的内容。
最后,学习如何使用 Range 对象。使用选择效率低且容易出错。
为了让您了解可能的情况,请在新的空文档中运行以下宏。这个宏只需要一次来配置模板。
Sub ApplyMultiLevelHeadingNumbers()
Dim LT As ListTemplate, i As Long
Set LT = ActiveDocument.ListTemplates.Add(OutlineNumbered:=True)
For i = 1 To 3
With LT.ListLevels(i)
.NumberFormat = Choose(i, "%1.", "(%2)", "%3.")
.TrailingCharacter = wdTrailingTab
.NumberStyle = Choose(i, wdListNumberStyleArabic, wdListNumberStyleLowercaseLetter, _
wdListNumberStyleArabic)
.NumberPosition = 0
.Alignment = wdListLevelAlignLeft
.TextPosition = InchesToPoints(0.5 + i * 0.5)
.ResetOnHigher = True
.StartAt = 1
.LinkedStyle = "Heading " & i
End With
With ActiveDocument.Styles("Heading " & i)
.ParagraphFormat.LeftIndent = InchesToPoints(i * 0.5 - 0.5)
.ParagraphFormat.FirstLineIndent = InchesToPoints(-0.5)
.ParagraphFormat.Alignment = wdAlignParagraphLeft
.Font.Name = "Times New Roman"
.Font.Bold = False
End With
Next
End Sub
然后运行以下宏:
Sub Demo()
Dim Rng As Range
With ActiveDocument
Set Rng = .Range(0, 0)
With Rng
.Text = "Para 1" & vbCr
.Paragraphs(1).Range.Style = wdStyleHeading1
.Start = .Paragraphs(1).Range.End
.Text = "Sub Para" & vbCr
.Paragraphs(1).Range.Style = wdStyleHeading2
.Start = .Paragraphs(1).Range.End
.Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa." & vbCr & _
"Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna." & vbCr & _
"Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus." & vbCr & _
"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci. Aenean nec lorem." & vbCr
.Style = wdStyleHeading3
.Start = .Paragraphs(4).Range.End
.Text = "Sub Para" & vbCr
.Paragraphs(1).Range.Style = wdStyleHeading2
.Start = .Paragraphs(1).Range.End
.Text = "In porttitor. Donec laoreet nonummy augue. Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc." & vbCr & _
"Mauris eget neque at sem venenatis eleifend. Ut nonummy. Fusce aliquet pede non pede. Suspendisse dapibus lorem pellentesque magna. Integer nulla." & vbCr & _
"Donec blandit feugiat ligula. Donec hendrerit, felis et imperdiet euismod, purus ipsum pretium metus, in lacinia nulla nisl eget sapien." & _
"Donec ut est in lectus consequat consequat. Etiam eget dui. Aliquam erat volutpat." & vbCr & _
"Sed at lorem in nunc porta tristique. Proin nec augue. Quisque aliquam tempor magna. " & _
"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nunc ac magna." & vbCr
.Style = wdStyleHeading3
.Start = .Paragraphs(4).Range.End
.Text = "Para 2" & vbCr
.Paragraphs(1).Range.Style = wdStyleHeading1
.Start = .Paragraphs(1).Range.End
.Text = "Sub Para" & vbCr
.Paragraphs(1).Range.Style = wdStyleHeading2
.Start = .Paragraphs(1).Range.End
.Start = .Paragraphs(1).Range.End
.Text = "Maecenas odio dolor, vulputate vel, auctor ac, accumsan id, felis. Pellentesque cursus sagittis felis." & vbCr
.Style = wdStyleHeading3
End With
End With
End Sub
正如您将看到的,输出的格式与您描述的一样,数据中没有一个选项卡。
关于excel - VBA TypeText Word Wrapping 内联与前一行的缩进,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67643750/
前一段时间写过一篇文章《 实战,一个高扩展、可视化低代码前端,详实、完整 》,得到了很多朋友的关注。 其中的逻辑编排部分过于简略,不少朋友希望能写一些关于逻辑编排的内容,本文就详细讲述一下逻辑
我正在尝试以下 Java 片段: int[] testArray={10,20,30,40}; int i= 0; testArray[i++]= testArray[i++]+1; System.o
我想知道我是否可以通过某种方式在 C++ 中进行前/后函数调用。我有一个包含很多函数的包装器类,在每次调用包装器函数后,我应该调用另一个始终相同的函数。 所以我不想像这样对每个函数调用 postFun
我有一个像这样的头文件: #pragma once #include "gamestate.h" #include "ExitListener.h" class InitialGameState :
学习左值和右值。定义是任何可以是“地址”的东西都是左值,否则就是右值。 我检查了运算符的优先级,前缀和后缀增量都比“地址”运算符具有更高的优先级。 对于下面的两个例子,谁能解释一下为什么第一个“&++
在我的学习过程中,我遇到了前后迭代器,我想知道是否有办法让它们就地创建容器元素。从文档来看,容器似乎需要实现 push_back 函数才能与 back_iterator 一起使用。但是有没有一种方法可
我有两个关于 Java 中运算符优先级的类似问题。 第一个: int X = 10; System.out.println(X++ * ++X * X++); //it prints 1440 根据
请放轻松,不要对我开枪,因为我还是新手。 当我运行这段代码时,我完全糊涂了,终生无法弄清楚为什么: int y = 9; cout << "++y = " << ++y << "\n--y = " <
两种表达方式有区别吗: (*x)++ 和 ++(*x) 我可以看到这两个语句都替换了 *x 中 (*x+1) 的内容。但是它们之间有什么区别吗? 最佳答案 (*x)++ 计算为*x的值;作为副作用,*
我有一个如下所示的数据集: Date CONSUMER DISCR CONSUMER STAPLES ENERGY FINANCIALS HEALTH CARE
我希望检查名称字段中输入的前两个字符是否为字母 - 除此之外没有什么区别(空格、'、- 等都是公平的游戏)。这是我到目前为止所拥有的,但它不起作用。想法?谢谢! if (document.form01
我制作了一个简单的脚本,为像素和所有附近的像素着色为相同的颜色 Click foto
我需要编写一个循环,以下列格式输出从昨天算起的最近 30 天: 2014-02-02 2014-02-03 2014-02-04 ... 2014-03-04 我想我需要像这样使用循环: for ($
我正在做一些练习,但我对这个感到困惑: public static int f (int x, int y) { int b=y--; while (b>0) { if (x%2!=0
我需要一个 4 个字符的正则表达式。前 3 个字符必须是数字,最后 1 个字符必须是字母或数字。 我形成了这个,但它不起作用 ^([0-9]{3}+(([a-zA-Z]*)|([0-9]*)))?$
我需要编写一个循环,以下列格式输出从昨天算起的最近 30 天: 2014-02-02 2014-02-03 2014-02-04 ... 2014-03-04 我想我需要像这样使用循环: for ($
我有下面的程序,我试图找到前 1000 个素数的总和。在代码中,解决方案1和2有什么区别?为什么我不应该将 count 变量放在 if 条件之外?如果我把变量放在 if 之外,我显然没有得到我需要的答
这个问题在这里已经有了答案: Replace First N Occurrences in the String (7 个答案) 关闭 4 年前。 我有一个如下的字符串 const str = '_
我正在尝试测量以纳秒为单位的平均访问延迟,但在第一次迭代后我收到“段错误(核心转储)”。我错过了什么吗?我是否滥用了指针。这是导致错误的函数: #include #include #include
我有一个 SQL 问题 (MySQL)。我如何从下表创建一个新表(表名称:“well_master_prod_inj”)。 我需要按井名和日期聚合数据。我希望每个井名只有一行数据以及显示以下数据的列:
我是一名优秀的程序员,十分优秀!