Как получить текст из текстовых полей и полей формы в Word 2013 с помощью Delphi XE7?

Я создал небольшую программу для чтения всего текста из .docx с помощью Delphi. Он работает с обычным текстом и с быстрыми частями, но ни одно из решений, которые я нашел на форумах и в учебных пособиях, не работает для моих текстовых полей или полей формы. Я использую Word 2013 и Delphi XE7, и мой документ имеет 2 поля формы, одно из которых называется «Имя», другое «Автор» и одно текстовое поле.

Вот мой код:

    procedure TForm1.Button1Click(Sender: TObject);
    var i: integer;
    begin
      WordApplication1.Disconnect;
      WordDocument1.Disconnect;
      try
        WordApplication1.Connect;
        WordApplication1.Visible := true;
        WordDocument1.ConnectTo(WordApplication1.Documents.Open(
          'C:\homelaufwerk\Documents\Embarcadero\Studio\Projekte\Word test\testDoc.docx',
          EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
          EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam));
        memo1.Clear;
        memo1.Text := '';

        for I := 1 to WordDocument1.Paragraphs.Count do
        begin
          memo1.Text := memo1.Text + WordDocument1.Paragraphs.Item(i).Range.Text + #13#10;
        end;

        memo1.Text := memo1.Text + WordApplication1.ActiveDocument.FormFields.Item('Author').Result;
        memo1.Text := memo1.Text + WordApplication1.ActiveDocument.FormFields.Item('Name').Result;

        for I := 1 to WordApplication1.ActiveDocument.Fields.Count do
        begin
          memo1.Text := memo1.Text + WordApplication1.ActiveDocument.Fields.Item(1).Result;
        end;

        WordDocument1.Close;

      except
        ShowMessage('Microsoft Word couldn''t start.');
      end;
    end;

Я также пробовал это для текстового поля:

    WordDocument1.Fields.Item(1).Select;
    memo1.Text := memo1.Text + WordApplication1.Selection.Text;

и везде я заменил WordApplication1.ActiveDocument.[...] на WordDocument1.[...] и наоборот...ничего не работает.

Когда я отлаживаю, функция .Count для текстового поля всегда возвращает 0, и при попытке получить .Result для полей формы я получаю сообщение об ошибке, что поля не могут быть найдены (не знаю формулировку ошибки на английском языке) .

Кто-нибудь знает, что я делаю неправильно и как это будет работать?

Заранее спасибо,

Леа


person Lea    schedule 07.09.2015    source источник


Ответы (1)


Чтобы получить доступ к быстрым частям и флажкам, вам необходимо получить доступ к ContentControls.

var
  ... // your other vars here
  LRange: OleVariant;
  LStartRange: Integer;
  LEndRange: Integer;
begin
  ...
  ... //here your code
  ...

  LStartRange := WordApplication1.ActiveDocument.Content.Start;
  LEndRange := WordApplication1.ActiveDocument.Content.End_;
  LRange := WordApplication1.ActiveDocument.Range(LStartRange, LEndRange);

  for I := 1 to LRange.ContentControls.Count do
    Memo1.Lines.Add(LRange.ContentControls.Item[I].Range.Text);

end;

P.S: Delphi Wrapper не содержит свойства ContentControls, поэтому вам нужно работать с Range как с OleVariant.

Обновлять:

Чтобы получить доступ к элементам текстового поля:

for I := 1 to WordApplication1.ActiveDocument.Shapes.Count do
  Memo1.Lines.Add(WordApplication1.ActiveDocument.Shapes.Item(I).TextFrame.TextRange.Text);
person Agustin Seifert    schedule 07.09.2015
comment
Я пробовал. это работало для полей форм, но не для моего текстового поля. Вместо того, чтобы получать содержимое текстового поля, я снова получил содержимое своей быстрой части. И можете ли вы объяснить мне, что это за элементы управления контентом? Мне нужно построить большую программу и получить для этого как можно больше информации. :) - person Lea; 07.09.2015
comment
Вы получаете доступ к текстовому полю через свойство Shapes - person Agustin Seifert; 07.09.2015
comment
хорошо, что работает для текстового поля. но я все равно получаю в 2 раза больше контента, чем quickpart. вот мой результат: Первая строка [#13#10] Вторая строка [#13#10] Третья строка [#13#10] [#13#10] Пятая строка – четвертая строка была пустой [#13#10] [# 13#10] Компания xy [#13#10] [#13#10] Автор [#13#10] Имя [#13#10] [#13#10] Компания xy [#13#10] [#13# 10] Это текстовое поле - person Lea; 08.09.2015
comment
Я отладил его.... Быстрая часть и поля формы уже прочитаны Memo1.Lines.Add(WordDocument1.Paragraphs.Item(i).Range.Text); Memo1.Lines.Add(LRange.ContentControls.Item(i).Range.Text); читает только быструю часть и Memo1.Lines.Add(WordApplication1.ActiveDocument.Shapes.Item(i).TextFrame.TextRange.Text); читает текстовое поле. - person Lea; 08.09.2015
comment
Если мой ответ поможет вам, пожалуйста, примите его. Спасибо! - person Agustin Seifert; 08.09.2015
comment
тогда, пожалуйста, исправьте свой ответ. я немного погуглил. первый код предназначен не для текстовых полей, а для флажков и тому подобного. и не могли бы вы взглянуть на мой следующий вопрос - person Lea; 08.09.2015