Нужно произвести поиск строки формата "\<\#*\>" в документе MSWord и получить массив вхождений (Region или начальная_конечная позиции, без разницы).
Такой способ ищет только в основном тексте документа, но не ищет в колонтитулах и надписях.
| Код | type TParamsFind2000 = record _FindText, _MatchCase, _MatchWholeWord, _MatchWildcards, _MatchSoundsLike, _MatchAllWordForms, _Forward, _Wrap, _Format, _ReplaceWith, _Replace, _MatchKashida, _MatchDiacritics, _MatchAlefHamza, _MatchControl: OleVariant; end; var vFindPar:TParamsFind2000; begin with vParFind do begin _FindText := '\<#*\>'; // Искомый текст _MatchCase := False; // Регистрозависимый? _MatchWholeWord := False; _MatchWildcards := True; _MatchSoundsLike := False; _MatchAllWordForms := False; _Forward := True; // Вперед // _Wrap := wdFindContinue; _Wrap := wdFindStop; _Format := False; _ReplaceWith := ''; _Replace := wdReplaceNone; // Способ замены (Не заменять|Все|Один) _MatchKashida := EmptyParam; _MatchDiacritics := EmptyParam; _MatchAlefHamza := EmptyParam; _MatchControl := EmptyParam; while fWApp.Selection.Find.Execute( _FindText, _MatchCase, _MatchWholeWord, _MatchWildcards, _MatchSoundsLike, _MatchAllWordForms, _Forward, _Wrap, _Format, _ReplaceWith, _Replace, _MatchKashida, _MatchDiacritics, _MatchAlefHamza, _MatchControl) do begin vTagText := fWApp.Selection.Text; vTagPosBeg := fWApp.Selection.Range.Start; vTagPosEnd := fWApp.Selection.Range.End_; if Assigned(fOnTagFound) then fOnTagFound(vTagText, vTagPosBeg); TagPosAdd(vTagText, vTagPosBeg, vTagPosEnd); end; end; end;
|
Надписи можно перебрать используя свойство Shapes.
| Код | var vCnrShapes:Integer; vCurShapeIndex:OleVariant; vCurShape:Shape; begin for vCnrShapes := 1 to fWDoc.Shapes.Count do begin vCurShapeIndex := vCnrShapes; vCurShape := fWDoc.Shapes.Item(vCurShapeIndex); if (vCurShape.type_ <> msoTextBox{17}) then Continue; //...текущий Shape является надписью end; end;
|
Но, как оказалось, надписи могут быть заключены в объект "Полотно" с типом 20. Тут я жестоко обломался. Информации никакой. У шейпа может быть TextFrame у которого есть диапазон TextRange, а может и не быть. Если он есть, то с ним можно работать как с обычным объектом Region.
| Код | var vFindRange, vCurRange :Region; begin vFindRange := fWDoc.Shapes.Item(vCurShapeIndex).TextFrame.TextRange; vCurRange := vFindRange; while vCurRange.Find.Execute( _FindText, _MatchCase, _MatchWholeWord, _MatchWildcards, _MatchSoundsLike, _MatchAllWordForms, _Forward, _Wrap, _Format, _ReplaceWith, _Replace, _MatchKashida, _MatchDiacritics, _MatchAlefHamza, _MatchControl) do begin if (vCurRange.Start >= vFindRange.Start)and(vCurRange.End_ <= vFindRange.End_) then begin vCurRange.Select; fLog.Lines.Add(fWApp.Selection.Range.Text); end; end; end;
|
Если нет, то при попытке обращения возникает исключение.
Как быть? Как достучаться до дочерних объектов? Или есть другой способ?
Кстати, сам Word ищет все вхождения легко и непринужденно. При этом получается такой вот макрос:
| Код | Sub Макрос1() Selection.Find.ClearFormatting With Selection.Find .Text = "\<\#*\>" .Replacement.Text = "" .Forward = True .Wrap = wdFindContinue .Format = False .MatchCase = False .MatchWholeWord = False .MatchAllWordForms = False .MatchSoundsLike = False .MatchWildcards = True End With Selection.Find.Execute Selection.Find.Execute Selection.Find.Execute ... ActiveWindow.Panes(2).Activate Selection.Find.Execute Selection.Find.Execute Selection.Find.ClearFormatting With Selection.Find .Text = "\<\#*\>" .Replacement.Text = "" .Forward = True .Wrap = wdFindAsk .Format = False .MatchCase = False .MatchWholeWord = False .MatchAllWordForms = False .MatchSoundsLike = False .MatchWildcards = True End With Selection.Find.Execute End Sub
|
В приаттаченом файле шаблон документа, который нужно обработать. |