0

我正在尝试将一些现有的 VBA 代码移植到 C#。一个例程控制项目符号的缩进,大致是:

indentStep = 13.5
For Each parag In shp.TextRange.Paragraphs()
    parag.Parent.Ruler.Levels(parag.IndentLevel).FirstMargin = indentStep * (parag.IndentLevel - 1)
    parag.Parent.Ruler.Levels(parag.IndentLevel).LeftMargin = indentStep * (parag.IndentLevel)
Next parag

该代码有效,但似乎是令人毛骨悚然的黑魔法。特别是,每次设置特定标尺的边距时,实际设置了所有九个标尺边距。但不知何故,正在设置适当的信息。不幸的是,当您在 C# 中执行相同的操作时,结果会发生变化。以下代码没有可见的效果:

const float kIndentStep = 13.5f;
foreach (PowerPoint.TextRange pg in shp.TextFrame.TextRange.Paragraphs())
{
pg.Parent.Ruler.Levels[pg.IndentLevel].FirstMargin = kIndentStep * (pg.IndentLevel - 1);
pg.Parent.Ruler.LevelS[pg.IndentLevel].LeftMargin = kIndentStep * pg.IndentLevel;
}
4

1 回答 1

0

从 C# 自动化 PowerPoint 时,这似乎是一个限制/错误。我确认它适用于 VBA。

代码运行后我确实看到了效果:每次运行都会更改第一级,因此最后第一级具有应该分配给要处理的最后一个级别的设置,但没有其他级别明显受到影响。我确实看到代码执行期间返回的值发生了变化,但仅此而已。

如果代码仅更改文本框架的一个特定级别,则它可以工作。仅在尝试更改多个级别时才会出现此问题。

我尝试了各种方法,包括后期绑定 (PInvoke) 并将更改放在单独的过程中,但结果始终相同。

这是我的最后一次迭代

Microsoft.Office.Interop.PowerPoint.Application pptApp = (Microsoft.Office.Interop.PowerPoint.Application) System.Runtime.InteropServices.Marshal.GetActiveObject("Powerpoint.Application"); // new Microsoft.Office.Interop.PowerPoint.Application();
//Change indent level of text
const float kIndentStep = 13.5f;
Microsoft.Office.Interop.PowerPoint.Shape shp = pptApp.ActivePresentation.Slides[2].Shapes[2];
Microsoft.Office.Interop.PowerPoint.TextFrame tf = shp.TextFrame;
object oTf = tf;
int indentLevelLast = 0;
foreach (Microsoft.Office.Interop.PowerPoint.TextRange pg in tf.TextRange.Paragraphs(-1, -1))
{
    int indentLevel = pg.IndentLevel;
    if (indentLevel > indentLevelLast)
    {
        Microsoft.Office.Interop.PowerPoint.RulerLevel rl = tf.Ruler.Levels[indentLevel];
        object oRl = rl;
        System.Diagnostics.Debug.Print(pg.Text + ": " + indentLevel + ", " + rl.FirstMargin.ToString() + ", " + rl.LeftMargin.ToString()) ;
        object fm = oRl.GetType().InvokeMember("FirstMargin", BindingFlags.SetProperty, null, oRl, new object[] {kIndentStep * (indentLevel - 1)});
        //rl.FirstMargin = kIndentStep * (indentLevel - 1);
        object lm = oRl.GetType().InvokeMember("LeftMargin", BindingFlags.SetProperty, null, oRl, new object[] { kIndentStep * (indentLevel) });
        //rl.LeftMargin = kIndentStep * indentLevel;
        indentLevelLast = indentLevel;
        System.Diagnostics.Debug.Print(pg.Text + ": " + indentLevel + ", " + tf.Ruler.Levels[indentLevel].FirstMargin.ToString() + ", " + tf.Ruler.Levels[indentLevel].LeftMargin.ToString()) ;
        rl = null;
    }
}

FWIW 问题中提供的代码片段都无法编译。缺少 VBA 片段.TextFrame。C# 片段不喜欢Parent.Ruler,所以我不得不将其更改为TextFrame.Ruler.

于 2019-02-25T13:49:55.043 回答