Пересмотрел кучу вопросов на эту тему и так ничего не помогло. Выводится или квадрат или просто как строка. Пробовал Символы.ПС, Символ(13) + Символ(10), ^|, ^p. В старом Word работал такой вариант
(4) Конфигурация у меня документооборот. Посмотрел в общем модуле, файл word заполняется с помощью xml. В коде нашел что символ переноса строки заменяется на <w:cr/>. Просто в тексте он отображается как абзац , но в таблице выводятся квадраты. Это получается что в таблице нельзя использовать абзац? (Извиняюсь, что сразу не уточнил)
(5) Я тоже поначалу перепутал с мягким переносом. На самом деле нужно передать в параметре перевод строки, который ранее передавался неким символом, который в новом ворде 2013 трактуется по-другому. Поэтому и переспрашиваю про процесс передачи, если это OLE, то в конце формирования можно сделать замену средствами самого Word. И попутно интересно, какой код символа или набор символов уходил вместо "|".
Дописал чтобы когда текст в таблице, то вместо переноса подставлялся <w:br/> вместо <w:cr/> , так работает.
1с похоже не пользуются новыми версиями MS Office...
(12)
<w:br/> помогает, но только первый раз.
При перезаполнении заполненного файла часть после <w:br/> задваивается, потом затраивается и так далее.
Михаил не победили это?
вдруг кому-нибудь еще понадобится решение:
нужно в коде процедуры АвтозаполнениеШаблоновФайловКлиентСервер.ВыполнитьЗаменуПолейИСтрокВДокументеMSOfficeOpenXML
перенести формирование строки образца таблицы
Если ФлагНайденаСтрокаТаблицы Тогда
КопияСтрокиXML.ЗаписатьБезОбработки(СтрЗамены);
КонецЕсли;
вдруг кому-нибудь еще понадобится решение:
нужно в коде процедуры АвтозаполнениеШаблоновФайловКлиентСервер.ВыполнитьЗаменуПолейИСтрокВДокументеMSOfficeOpenXML
перенести формирование строки образца таблицы
Если ФлагНайденаСтрокаТаблицы Тогда
КопияСтрокиXML.ЗаписатьБезОбработки(СтрЗамены);
КонецЕсли;
выше ее заполнения.
Не помогло. Вообще не ясно что и куда переносить. Решили проблему созданием дополнительного пустого автозаполняемого текстового поля непосредственно перед редактируемым текстом. Но пришлось это поле защищать паролем от случайного удаления пользователем.
А именно что изменил: изменения помечены как //Корректировка
Код всей процедуры
// Получаем количество строк в таблице товары, если она заполнена.
КоличествоСтрок = 0;
Для Каждого Настройка Из МассивДанныхДляАвтоЗамен Цикл
Если Настройка.НомерКолонкиТабличнойЧасти = 1 Тогда
КоличествоСтрок = Настройка.ЗначениеЗамены.Количество();
Прервать;
КонецЕсли;
КонецЦикла;
ЧтениеXML.ИгнорироватьПробелы = Ложь;
ФлагНайденоПоле = Ложь;
ФлагНайденаСтрока = Ложь;
ПереводСтроки = Ложь; ВозможенПереводСтроки = Ложь;
СтрЗамены = "";
СтрПоиска = "";
ТекстБылЗаписан = Ложь;
СтрокаТаблицы = 0; НомерКолонки = 0;
ФлагНайденаТаблица = Ложь; ФлагНайденаНашаТаблица = Ложь;
ФлагНайденаСтрокаТаблицы = Ложь;
ПервыйТег = КоличествоСтрок > 1; ПропуститьСтроку = Ложь;
СтрокаXMLОткрыт = Ложь;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
// Найдено предполагаемое поле для замены
Если ЧтениеXML.Имя = "w:bookmarkStart" Тогда
ФлагНайденоПоле = Истина;
СкрытаяЗакладка = Ложь;
КонецЕсли;
Если ЧтениеXML.Имя = "w:t" Тогда
ФлагНайденаСтрока = Истина;
КонецЕсли;
// Предполагаем, что найдена наша таблица для замены
//Корректировка++
Если ЧтениеXML.Имя = "w:tbl" Тогда //Было: Если ЧтениеXML.Имя = "w:tbl" И КоличествоСтрок > 0 Тогда
//Корректировка++
ФлагНайденаТаблица = Истина;
СтрокаТаблицы = 0;
КонецЕсли;
// Предполагаем, что найдена строка нашей таблица для замены
Если ЧтениеXML.Имя = "w:tr" И ФлагНайденаТаблица Тогда
Если СтрокаТаблицы > КоличествоСтрок И ФлагНайденаНашаТаблица Тогда
ПропуститьСтроку = Истина;
Продолжить;
КонецЕсли;
СтрокаТаблицы = СтрокаТаблицы + 1;
Если СтрокаТаблицы = 2 И КоличествоСтрок > 1 Тогда
ФлагНайденаСтрокаТаблицы = Истина;
КонецЕсли;
КонецЕсли;
Если ЧтениеXML.Имя = "w:tc" Тогда
НомерКолонки = НомерКолонки + 1;
КонецЕсли;
// В случае перезаполнения файла, этот тег пропускаем, чтобы не создавались лишние переводы строки.
//Корректировка++
Если ЧтениеXML.Имя = "w:cr" ИЛИ ЧтениеXML.Имя = "w:br" И ВозможенПереводСтроки Тогда //Было: Если ЧтениеXML.Имя = "w:cr" И ВозможенПереводСтроки Тогда
//Корректировка--
ПереводСтроки = Истина;
Продолжить;
КонецЕсли;
Если ПропуститьСтроку Тогда
Продолжить;
КонецЕсли;
ЗаписьXML.ЗаписатьНачалоЭлемента(ЧтениеXML.Имя);
Если ПервыйТег Или ФлагНайденаСтрокаТаблицы Тогда
Если Не СтрокаXMLОткрыт Тогда
КопияСтрокиXML = СоздатьНовуюЗапись(АдресXML);
СтрокаXMLОткрыт = Истина;
КонецЕсли;
КопияСтрокиXML.ЗаписатьНачалоЭлемента(ЧтениеXML.Имя);
КонецЕсли;
// Читаем и записываем атрибуты тега
Если ЧтениеXML.КоличествоАтрибутов() > 0 Тогда
Пока ЧтениеXML.ПрочитатьАтрибут() Цикл
Если ФлагНайденоПоле И ЧтениеXML.Имя = "w:name"
И Найти(ЧтениеXML.Значение, "_GoBack") = 0 Тогда
СтрПоиска = ЧтениеXML.Значение;
// Скрытые закладки начинаются с символа "_"
Если Лев(ЧтениеXML.Значение, 1) = "_" Тогда
СкрытаяЗакладка = Истина;
КонецЕсли;
Если ФлагНайденаТаблица И Не ФлагНайденаНашаТаблица Тогда
Для Каждого НастройкаЗамены Из МассивДанныхДляАвтоЗамен Цикл
Если НастройкаЗамены.ТермДляЗамены = СтрПоиска
И НастройкаЗамены.НомерКолонкиТабличнойЧасти > 0 Тогда
ФлагНайденаНашаТаблица = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ПервыйТег Или ФлагНайденаСтрокаТаблицы Тогда
КопияСтрокиXML.ЗаписатьАтрибут(ЧтениеXML.Имя, Лев(СтрПоиска, 19) + "1");
КонецЕсли;
ИначеЕсли ПервыйТег Или ФлагНайденаСтрокаТаблицы Тогда
КопияСтрокиXML.ЗаписатьАтрибут(ЧтениеXML.Имя, ЧтениеXML.Значение);
КонецЕсли;
ЗаписьXML.ЗаписатьАтрибут(ЧтениеXML.Имя, ЧтениеXML.Значение);
КонецЦикла
КонецЕсли;
ПервыйТег = Ложь;
// Текст тега
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
Если ПереводСтроки И ВозможенПереводСтроки Тогда
ЗаписьXML.ЗаписатьБезОбработки("");
// Перезаполняем поля таблицы
ИначеЕсли ФлагНайденаНашаТаблица И ФлагНайденоПоле И ФлагНайденаСтрока Тогда
Если ПропуститьСтроку Тогда
Продолжить;
КонецЕсли;
СтрЗамены = ЧтениеXML.Значение;
БылаВыполненаЗамена = Ложь;
Если ЗначениеЗаполнено(СтрЗамены) Тогда
Для Каждого НастройкаЗамены Из МассивДанныхДляАвтоЗамен Цикл
ИмяРеквизита = СтрЗаменить(Лев(НастройкаЗамены.ТермДляЗамены, 20), " ", "_");
Если ИмяРеквизита <> СтрПоиска Тогда
Продолжить;
КонецЕсли;
СтрЗамены = НастройкаЗамены.ЗначениеЗамены[СтрокаТаблицы - 2].Значение;
БылаВыполненаЗамена = Истина;
Прервать;
КонецЦикла;
КонецЕсли;
Если БылаВыполненаЗамена И Найти(СтрЗамены, Символы.ПС) > 0 Тогда
СтрЗамены = СтрЗаменить(СтрЗамены, Символы.ПС, "<w:cr/>");
Если СтрЗамены <> ЧтениеXML.Значение Тогда
ЗаписьXML.ЗаписатьБезОбработки(СтрЗамены);
Если ФлагНайденаСтрокаТаблицы Тогда
КопияСтрокиXML.ЗаписатьБезОбработки(СтрЗамены);
КонецЕсли;
Иначе
ЗаписьXML.ЗаписатьТекст(СтрЗамены);
Если ФлагНайденаСтрокаТаблицы Тогда
КопияСтрокиXML.ЗаписатьТекст(СтрЗамены);
КонецЕсли;
КонецЕсли;
Иначе
ЗаписьXML.ЗаписатьТекст(СтрЗамены);
Если ФлагНайденаСтрокаТаблицы Тогда
КопияСтрокиXML.ЗаписатьТекст(СтрЗамены);
КонецЕсли;
КонецЕсли;
СтрЗамены = "";
ФлагНайденоПоле = Ложь;
// Перезаполняем поля документа
ИначеЕсли ФлагНайденоПоле И ФлагНайденаСтрока Тогда
Для Каждого НастройкаЗамены Из МассивДанныхДляАвтоЗамен Цикл
ИмяРеквизита = СтрЗаменить(Лев(НастройкаЗамены.ТермДляЗамены, 20), " ", "_");
Если ИмяРеквизита = СтрПоиска Тогда
СтрЗамены = НастройкаЗамены.ЗначениеЗамены;
Прервать;
КонецЕсли;
КонецЦикла;
СтрЗаменыССимволамиПС = СтрЗамены;
СтрЗамены = СтрЗаменить(СтрЗамены, Символы.ПС, "<w:cr/>");
//Корректировка++ Если текст внутри таблицы, то docx в качестве символа переноса принимает только <w:br/>
Если ФлагНайденаТаблица Тогда
СтрЗамены = СтрЗаменить(СтрЗамены, "<w:cr/>", "<w:br/>");
КонецЕсли;
//Корректировка--
Если ЗначениеЗаполнено(СтрЗамены) Тогда
Если СтрЗамены <> СтрЗаменыССимволамиПС Тогда
ЗаписьXML.ЗаписатьБезОбработки(СтрЗамены);
Иначе
ЗаписьXML.ЗаписатьТекст(СтрЗамены);
КонецЕсли;
ИначеЕсли Не СкрытаяЗакладка И СтрЗамены <> ЧтениеXML.Значение Тогда
ЗаписьXML.ЗаписатьТекст(Символ(160));
Иначе
ЗаписьXML.ЗаписатьТекст(ЧтениеXML.Значение);
КонецЕсли;
ФлагНайденоПоле = Ложь;
СтрЗамены = "";
ВозможенПереводСтроки = Истина;
// Перезаполняем строки документа
ИначеЕсли ФлагНайденаСтрока Тогда
СтрЗамены = ЧтениеXML.Значение;
БылаВыполненаЗамена = Ложь;
Для Каждого НастройкаЗамены Из МассивДанныхДляАвтоЗамен Цикл
Если Не ЗначениеЗаполнено(НастройкаЗамены.ЗаменяемаяСтрока) Тогда
Продолжить;
КонецЕсли;
Если Найти(СтрЗамены, НастройкаЗамены.ЗаменяемаяСтрока) > 0 Тогда
СтрЗамены = СтрЗаменить(СтрЗамены, НастройкаЗамены.ЗаменяемаяСтрока, НастройкаЗамены.ЗначениеЗамены);
БылаВыполненаЗамена = Истина;
КонецЕсли;
КонецЦикла;
Если БылаВыполненаЗамена И Найти(СтрЗамены, Символы.ПС) > 0 Тогда
СтрЗамены = СтрЗаменить(СтрЗамены, Символы.ПС, "<w:cr/>");
Если СтрЗамены <> ЧтениеXML.Значение Тогда
ЗаписьXML.ЗаписатьБезОбработки(СтрЗамены);
Иначе
ЗаписьXML.ЗаписатьТекст(СтрЗамены);
КонецЕсли;
Иначе
ЗаписьXML.ЗаписатьТекст(СтрЗамены);
КонецЕсли;
Иначе
ЗаписьXML.ЗаписатьТекст(ЧтениеXML.Значение);
Если ФлагНайденаСтрокаТаблицы Тогда
КопияСтрокиXML.ЗаписатьТекст(ЧтениеXML.Значение);
КонецЕсли;
КонецЕсли;
// Читаем и записываем конец тега
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
// В случае перезаполнения файла, этот тег пропускаем, чтобы не создавались лишние переводы строки.
//Корректировка++
Если ЧтениеXML.Имя = "w:cr" ИЛИ ЧтениеXML.Имя = "w:br" И ВозможенПереводСтроки Тогда //Было: Если ЧтениеXML.Имя = "w:cr" И ВозможенПереводСтроки Тогда
//Корректировка--
Продолжить;
КонецЕсли;
Если ФлагНайденаТаблица И ЧтениеXML.Имя = "w:tbl" Тогда
ФлагНайденаТаблица = Ложь;
ФлагНайденаНашаТаблица = Ложь;
ПропуститьСтроку = Ложь;
СтрЗамены = "";
КонецЕсли;
Если ПропуститьСтроку Тогда
Продолжить;
КонецЕсли;
ЗаписьXML.ЗаписатьКонецЭлемента();
Если ФлагНайденаСтрокаТаблицы Тогда
КопияСтрокиXML.ЗаписатьКонецЭлемента();
КонецЕсли;
Если ФлагНайденоПоле И ЧтениеXML.Имя = "w:bookmarkEnd" Тогда
ФлагНайденоПоле = Ложь; СкрытаяЗакладка = Ложь;
СтрЗамены = "";
КонецЕсли;
Если ФлагНайденаСтрока Тогда
ФлагНайденаСтрока = Ложь;
СтрЗамены = "";
КонецЕсли;
Если ЧтениеXML.Имя = "w:tr" И ФлагНайденаТаблица Тогда
НомерКолонки = 0;
ФлагНайденаСтрокаТаблицы = Ложь;
Если СтрокаТаблицы = 2 И КоличествоСтрок > 1 Тогда
КопияСтрокиXML.ЗаписатьКонецЭлемента();
КопияСтрокиXML.Закрыть();
СтрокаXMLОткрыт = Ложь;
ЗаменитьПространствоИменR(АдресXML);
// Добавление в документ копии первой строки таблицы, с последующим заполнением данными документа
Если ФлагНайденаНашаТаблица Тогда
Пока СтрокаТаблицы - 1 < КоличествоСтрок Цикл
ЧтениеСтрокиXML = Новый ЧтениеXML();
ЧтениеСтрокиXML.ОткрытьФайл(АдресXML);
ЧтениеСтрокиXML.ИгнорироватьПробелы = Ложь;
ФлагНайденоПоле = Ложь; ФлагНайденаСтрока = Ложь;
Пока ЧтениеСтрокиXML.Прочитать() Цикл
Если ЧтениеСтрокиXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
// Первый тег пропускаем
Если ЧтениеСтрокиXML.Имя = "w:document" Тогда
Продолжить;
КонецЕсли;
Если ЧтениеСтрокиXML.Имя = "w:bookmarkStart" Тогда
ФлагНайденоПоле = Истина;
КонецЕсли;
Если ЧтениеСтрокиXML.Имя = "w:t" Тогда
ФлагНайденаСтрока = Истина;
КонецЕсли;
Если ЧтениеСтрокиXML.Имя = "w:tr" Тогда
СтрокаТаблицы = СтрокаТаблицы + 1;
КонецЕсли;
Если ЧтениеСтрокиXML.Имя = "w:tc" Тогда
НомерКолонки = НомерКолонки + 1;
КонецЕсли;
// В случае перезаполнения файла, этот тег пропускаем, чтобы не создавались лишние переводы строки.
Если ЧтениеСтрокиXML.Имя = "w:cr" И ВозможенПереводСтроки Тогда
ПереводСтроки = Истина;
Продолжить;
КонецЕсли;
ЗаписьXML.ЗаписатьНачалоЭлемента(ЧтениеСтрокиXML.Имя);
Если ЧтениеСтрокиXML.КоличествоАтрибутов() > 0 Тогда
Пока ЧтениеСтрокиXML.ПрочитатьАтрибут() Цикл
Если ФлагНайденоПоле И ЧтениеСтрокиXML.Имя = "w:name"
И Найти(ЧтениеXML.Значение, "_GoBack") = 0 Тогда
СтрПоиска = ЧтениеСтрокиXML.Значение;
КонецЕсли;
ЗаписьXML.ЗаписатьАтрибут(ЧтениеСтрокиXML.Имя, ЧтениеСтрокиXML.Значение);
КонецЦикла
КонецЕсли;
ИначеЕсли ЧтениеСтрокиXML.ТипУзла = ТипУзлаXML.Текст Тогда
Если ПереводСтроки И ВозможенПереводСтроки Тогда
ЗаписьXML.ЗаписатьБезОбработки("");
ИначеЕсли ФлагНайденоПоле И ФлагНайденаСтрока Тогда
СтрЗамены = ЧтениеСтрокиXML.Значение;
БылаВыполненаЗамена = Ложь;
Для Каждого НастройкаЗамены Из МассивДанныхДляАвтоЗамен Цикл
ИмяРеквизита = Лев(НастройкаЗамены.ТермДляЗамены, 19) + "1";
Если ИмяРеквизита <> СтрПоиска Тогда
Продолжить;
КонецЕсли;
СтрЗамены = НастройкаЗамены.ЗначениеЗамены[СтрокаТаблицы - 2].Значение;
БылаВыполненаЗамена = Истина;
Прервать;
КонецЦикла;
Если БылаВыполненаЗамена И Найти(СтрЗамены, Символы.ПС) > 0 Тогда
СтрЗамены = СтрЗаменить(СтрЗамены, Символы.ПС, "<w:cr/>");
Если СтрЗамены <> ЧтениеСтрокиXML.Значение Тогда
ЗаписьXML.ЗаписатьБезОбработки(СтрЗамены);
Иначе
ЗаписьXML.ЗаписатьТекст(СтрЗамены);
КонецЕсли;
Иначе
ЗаписьXML.ЗаписатьТекст(СтрЗамены);
КонецЕсли;
СтрЗамены = "";
ФлагНайденоПоле = Ложь;
Иначе
ЗаписьXML.ЗаписатьТекст(ЧтениеСтрокиXML.Значение);
КонецЕсли;
ИначеЕсли ЧтениеСтрокиXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
// В случае перезаполнения файла, этот тег пропускаем, чтобы не создавались лишние переводы строки.
Если ЧтениеСтрокиXML.Имя = "w:cr" И ВозможенПереводСтроки Тогда
Продолжить;
КонецЕсли;
Если ЧтениеСтрокиXML.Имя = "w:document" Тогда
Продолжить;
КонецЕсли;
ЗаписьXML.ЗаписатьКонецЭлемента();
Если ФлагНайденоПоле И ЧтениеСтрокиXML.Имя = "w:bookmarkEnd" Тогда
ФлагНайденоПоле = Ложь;
СтрЗамены = "";
КонецЕсли;
Если ФлагНайденаСтрока Тогда
ФлагНайденаСтрока = Ложь;
СтрЗамены = "";
КонецЕсли;
Если ЧтениеСтрокиXML.Имя = "w:tr" Тогда
НомерКолонки = 0;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЧтениеСтрокиXML.Закрыть();
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ВозможенПереводСтроки И ЧтениеXML.Имя = "w:bookmarkEnd" Тогда
ПереводСтроки = Ложь;
ВозможенПереводСтроки = Ложь;
КонецЕсли;
КонецЕсли;
КонецЦикла;
А именно что изменил: изменения помечены как //Корректировка
Большое спасибо! Сам не осилил, так как при чтении атрибутов во время отладки творилось что-то странное.
Считанные данные в табло отображались корректно, а по Shift + F9 переменные были пустыми.
Возможно причина была в платформе.
(22) при этом способе не сохраняется отступ первой строки в абзаце. Во второй и последующих строк текст начинается без отступа.
Может кто знает, как победить?
(26) Больше интересно, почему не работают символы перевода строки и возврата каретки(точнее не во всех случаях!), и есть ли более верный и 100% рабочий способ переноса строки
(28) в docx бы.
Замена на символ возврата каретки дает новую проблему: вторая и последующая строки в многострочном тексте становятся без отступа абзаца (красной строки)
Покопался в этой теме в связи с одной задачей по переходу на новые строки и обнаружил, что сочетание Символы.ВК + Символы.ПС спокойно воспринимается Вордом 2013 как переход на новую строку. Так что все костыли с символами и заменами для обеспечения перехода на новую строку вовсе не нужны.
(29) В Office 2016 перевод строки срабатывает благодаря Символы.ВК (неожиданно), но при этом в нумерованном списке не проставляется следующий номер, а Символы.ПС просто превращается в квадрат. Для Шестнадцатого ворда единственное рабочее решение - "символ(94) + символ(112)".