Заполняю договор в ворде из 1С.
Документ = ПолучитьCOMОбъект(«»,»Word.Application»);
Документ.Documents.Open(Константы.ИмяШаблонаДоговора.Получить());
//Документ.ActiveDocument;
Замена = Документ.ActiveDocument.Range().Find;
Замена.Execute(«пНомерДоговора», Ложь, Истина, Ложь, , , Истина, , Ложь, ОбщегоНазначения.ПолучитьНомерНаПечать(ЭтотОбъект));
Замена = Документ.ActiveDocument.Range().Find;
Замена.Execute(«пДатаДоговора», Ложь, Истина, Ложь, , , Истина, , Ложь, Формат(Дата, «ДЛФ=DD»));
Замена = Документ.ActiveDocument.Range().Find;
Замена.Execute(«пТуристы», Ложь, Истина, Ложь, , , Истина, , Ложь, ПолучитьТекстТуристов());
Проблема возникает с третьей заменой, так как ПолучитьТекстТуристов() возвращает длинную строку.
Как можно решить задачу?
Слишком длинный строковый параметр.
Автор Rust, 03 апр 2017, 07:42
0 Пользователей и 1 гость просматривают эту тему.
Здравствуйте!
При замене текста в word(execute),использовав более 255 символов-ошибка: Слишком длинный строковый параметр.
Как разбить строку на части?
Цитата: Rust от 03 апр 2017, 07:42
Здравствуйте!
При замене текста в word(execute),использовав более 255 символов-ошибка: Слишком длинный строковый параметр.Как разбить строку на части?
Гугл выдал следующее:
цитата «Разбиваешь вставляемую строку на строку с количеством символов 255-ДлинаСтроки(«{«+Элемент.Ключ+»}»)
потом к каждой отрезанной части перед вставкой в ворд дописываешь «{«+Элемент.Ключ+»}» вот и всё.
Таким образом у тебя цикл будет постоянно находить ту часть, которую надо заменить твоим длинным текстом и по кускам ты его заменишь»
Не знаю можно ли тут кидать ссылки на другие сайты, поэтому рекомендую самостоятельно погуглить.
Не помощь, но зато совет
Цитата: Norfolk от 03 апр 2017, 07:57
Цитата: Rust от 03 апр 2017, 07:42
Здравствуйте!
При замене текста в word(execute),использовав более 255 символов-ошибка: Слишком длинный строковый параметр.Как разбить строку на части?
Гугл выдал следующее:
цитата «Разбиваешь вставляемую строку на строку с количеством символов 255-ДлинаСтроки(«{«+Элемент.Ключ+»}»)
потом к каждой отрезанной части перед вставкой в ворд дописываешь «{«+Элемент.Ключ+»}» вот и всё.
Таким образом у тебя цикл будет постоянно находить ту часть, которую надо заменить твоим длинным текстом и по кускам ты его заменишь»
Не знаю можно ли тут кидать ссылки на другие сайты, поэтому рекомендую самостоятельно погуглить.
Не помощь, но зато совет
Большое спасибо!Встречал этот вариант.Но,не понимаю как это реализовать.Поэтому обратился сюда
Добавлено: 03 апр 2017, 09:36
ЗаменаКонтента.Execute(«[Комментарий1Замена]»,,,,,,,,,Комментарий1,2);
свой код работы с Вордом выкладывайте, (тот код где возникает ошибка +/- десяток команд
тогда можно будет подсказать конкретнее.
если помогло нажмите: Спасибо!
WordApplication = Новый COMОбъект("WORD.Application");
WordApplication.DisplayAlerts = 0; // не выводить предупреждения
Зак = WordApplication .Documents.Add(ПутьКЗаключению);
Комментарий1=Док.Комментарий1;
ЗаменаКонтента = Зак.content.Find;
ЗаменаКонтента.Execute("[Комментарий1Замена]",,,,,,,,,Комментарий1,2);
Не дает вставить более 255 символов.
Знаю что нужно разбить эту строку,(Как в совете выше) Но незнаю как.
Добавлено: 03 апр 2017, 10:06
Цитата: LexaK от 03 апр 2017, 09:44
свой код работы с Вордом выкладывайте, (тот код где возникает ошибка +/- десяток команд
тогда можно будет подсказать конкретнее.
WordApplication = Новый COMОбъект("WORD.Application");
WordApplication.DisplayAlerts = 0; // не выводить предупреждения
Зак = WordApplication .Documents.Add(ПутьКЗаключению);
Комментарий1=Док.Комментарий1;
ЗаменаКонтента = Зак.content.Find;
ЗаменаКонтента.Execute("[Комментарий1Замена]",,,,,,,,,Комментарий1,2);
Не дает вставить более 255 символов.
Знаю что нужно разбить эту строку,(Как в совете выше) Но незнаю как.
попробуйте так, должно сработать
WordApplication = Новый COMОбъект("WORD.Application");
WordApplication.DisplayAlerts = 0; // не выводить предупреждения
Зак = WordApplication .Documents.Add(ПутьКЗаключению);
Комментарий1=Док.Комментарий1;
ЗаменаКонтента = Зак.content.Find;
//заменено на цикл, ниже
//ЗаменаКонтента.Execute("[Комментарий1Замена]",,,,,,,,,Комментарий1,2);
//разбивка замены по 200 символов
лкВсяДлина = СтрДлина(Комментарий1);
лкТекущаяПозиция = 1;
лкКлюч = "[Комментарий1Замена]";
Пока лкТекущаяПозиция < лкВсяДлина Цикл
лкЧасть = Сред(Комментарий1, лкТекущаяПозиция, 200) + лкКлюч;
ЗаменаКонтента.Execute(лкКлюч,,,,,,,,,лкЧасть,2);
лкТекущаяПозиция = лкТекущаяПозиция + 200;
КонецЦикла;
//так как у вас ключ текстовый - чистим ключ
ЗаменаКонтента.Execute(лкКлюч,,,,,,,,,"",2);
если помогло нажмите: Спасибо!
Цитата: LexaK от 03 апр 2017, 10:13
попробуйте так, должно сработать
WordApplication = Новый COMОбъект("WORD.Application");
WordApplication.DisplayAlerts = 0; // не выводить предупрежденияЗак = WordApplication .Documents.Add(ПутьКЗаключению);
Комментарий1=Док.Комментарий1;
ЗаменаКонтента = Зак.content.Find;
//заменено на цикл, ниже
//ЗаменаКонтента.Execute("[Комментарий1Замена]",,,,,,,,,Комментарий1,2);//разбивка замены по 200 символов
лкВсяДлина = СтрДлина(Комментарий1);
лкТекущаяПозиция = 1;
лкКлюч = "[Комментарий1Замена]";
Пока лкТекущаяПозиция < лкВсяДлина Цикл
лкЧасть = Сред(Комментарий1, лкТекущаяПозиция, 200) + лкКлюч;
ЗаменаКонтента.Execute(лкКлюч,,,,,,,,,лкЧасть,2);
лкТекущаяПозиция = лкТекущаяПозиция + 200;
КонецЦикла;
//так как у вас ключ текстовый - чистим ключ
ЗаменаКонтента.Execute(лкКлюч,,,,,,,,,"",2);
Спасибо!Помогло!:)
Цитата: LexaK от 03 апр 2017, 10:13
попробуйте так, должно сработать
WordApplication = Новый COMОбъект("WORD.Application");
WordApplication.DisplayAlerts = 0; // не выводить предупрежденияЗак = WordApplication .Documents.Add(ПутьКЗаключению);
Комментарий1=Док.Комментарий1;
ЗаменаКонтента = Зак.content.Find;
//заменено на цикл, ниже
//ЗаменаКонтента.Execute("[Комментарий1Замена]",,,,,,,,,Комментарий1,2);//разбивка замены по 200 символов
лкВсяДлина = СтрДлина(Комментарий1);
лкТекущаяПозиция = 1;
лкКлюч = "[Комментарий1Замена]";
Пока лкТекущаяПозиция < лкВсяДлина Цикл
лкЧасть = Сред(Комментарий1, лкТекущаяПозиция, 200) + лкКлюч;
ЗаменаКонтента.Execute(лкКлюч,,,,,,,,,лкЧасть,2);
лкТекущаяПозиция = лкТекущаяПозиция + 200;
КонецЦикла;
//так как у вас ключ текстовый - чистим ключ
ЗаменаКонтента.Execute(лкКлюч,,,,,,,,,"",2);
Если в Док.Комментарий1 будет один символ, то не сработает. Надо
Пока лкТекущаяПозиция <= лкВсяДлина Цикл
Всем привет, сегодня снова работаем с эксель таблицей и шаблоном в ворд, в этом видео я вам покажу как работать с большим текстом, если у нас допустим, в нашей ячейке будет содержаться текста значительно больше чем 255 символов.
С этим вы обычной можете столкнуться при создании шаблона, для экспорта данных из эксель в ворд, при замене текста, дополнительно я покажу как исправить еще одну ошибку.
Давайте возьмём пример из первого видео, перейдете по ссылке в описании на странице есть файл в архиве.
Давайте сделаем так что у нас в заголовке таблицы будет не адрес, а текст для примера. Будем практиковаться на основе ячейки C2
.
Давайте сделаем проверку длинны текста в ячейке, используя функцию ДЛСТР — длина строки. У нас здесь сейчас находится 15 символов.
Сделаем больше текста для этого я в Microsoft Word используя функцию LOREM()
, которая сформирует случайный текст.
Теперь я скопирую текст, нужен будет блокнот, вставлю текст из буфера обмена, уберу лишние отступы переносы.
Давайте посмотрим какой длины у нас получится сейчас этот текст. Так вот у нас даже не помещается текст на экране, поправим таблицу. Длина текста в ячейке 598 символов с пробелами.
Давайте перейдём в Редактор Visual Basic, alt+f11
и посмотрим код прошлого примера.
Исправим название переменной адрес на текст, здесь исправим на текст и посмотрим что у нас получится.
Теперь откроем шаблон и заменим Адрес на Текст и исправим конструкцию для замены на &text
.
Сохраним, закроем все лишнее, совместим для наглядности эксель файл и папку для вывода ворд файлов.
Посмотрим, что теперь получится, изменю масштаб, для доступа к кнопке запуска макроса.
Появляется ошибка № 5854 — слишком длинный строковый параметр.
И хотя бланк сформировался, произошло не то что ожидалось, ID
вывели, серийный номер не изменился, потому как по коду данного макроса, мы не дошли до номера мы остановились вот здесь, ошибка произошла выше.
Давайте откроем диспетчер задач, существует проблема которую мы сейчас решим, иначе у нас при любой ошибке в работе макроса в Диспетчере задач в фоне остается запущен экземпляр Microsoft Word в котором рухнул наш шаблон.
Давайте ещё раз попробуем сформировать посмотрим, что у изменится.
Опять ошибка, и сейчас в Диспетчере задач повис Microsoft Word, его нужно закрыть и так придется делать постоянно, будем снимать задачу иначе будут появляться новые ошибки.
Давайте теперь сделаем выход из нашей функции, где мои работаем, здесь у нас создание файла проходит нормально, этот кусок у нас нормально отрабатывает.
Вставим вот здесь следующий код:
On Error GoTo ErrorHadler
Это у нас метка перехода, если произойдет ошибка, мы перейдём в конец модуля, вот здесь мы сделаем Exit Sub
— Выход из модуля.
Ниже напишем ErrorHandler:
наша метка и здесь нам нужно будет вставить код сохранения, закрытия и выхода из Word.
wdDoc.Save wdDoc.Close wdApp.Quit
Также добавим сообщение
MsgBox "Не выполнено! " + Error
Вот теперь мы избавимся проблемы, когда у нас будет зависать в Диспетчере задач Microsoft Word, который мы не успеваем закрыть.
Давайте выполним макрос, появится сообщение — не выполнено слишком длинный строковый параметр, в принципе у нас документ сформировался, но он в целом не полностью отработал.
Сейчас мы исправим эту проблему, кстати гляну в диспетчер задач у нас Microsoft Word нигде не висит, и он нам не мешает. OK.
Теперь снова перейдём в редактор VBA. и разобьем переменную Text$
на фрагменты допустимой длины.
Ну кроме исправлю маленькую опечатку, тут естественно должен быть &text
.
Дайте я посмотрю, что изменится, хотя даже если мы исправили это значение, всё равно ничего не получилось.
Теперь удалим снова бланк, вернемся вот сюда, зададим переменную temp равно Left
возьмём от переменной Text$
255 символов, снова создадим переменную temp2, воспользуемся теперь функцией Mid
, мы возьмём начиная с 256 символа текст длиной 255 символов.
Теперь нужно будет продублировать здесь строку для замены значений, укажем переменные temp
, temp2
, здесь мы сделаем заменяемое значение text2
.
Сделаем с запасом, ещё разок скопирую и вставлю
temp3 = Mid(Text$, 512, 255).
Теперь мы шагнем от 256 + 255 равно 511, начиная с 512 символа мы опять шагнем на 255 символов.
Ещё продублирую строку замены, переменная temp3
, значение text3
.
Как нам указать в шаблоне заменяемые значения? А мы их ведем просто в наш шаблон, уже есть вот эта строка &text
, мы её скопируем и вставим несколько раз, дописав числа 2 и 3.
То есть у нас всякий раз вот этот фрагмент текст будет заменяться на значения из наших переменных temp
, temp2
, temp3
. Можно в коде VBA продолжать добавлять разбивку основного текста на части, но будьте внимательны, указывая смещение и длину символов. Соответствующе правки так же вносите в шаблон.
Давайте попробуем запустить и посмотрим, что получится, закрыли, свернули.
Впишемся ли мы в данное ограничение, О’кей, готово.
Так давайте наконец посмотрим, что у нас получилось, как видите текст у нас вместился полностью, единственное хочу заметить, что между предложениями появился квадрат со знаком вопроса, но это символ переноса строк, при подготовке текста в ячейке его нужно заменить пробелом.
Следующие файлы так же сформировались, но тут у нас все осталось как обычно.
Вот таким простым способом вы можете обойти эту условность, ограничение в 255 символов, в принципе сама строковая переменная Text$ может очень много вместить в себя значений, но при работе вот этой функции FindText замена текста, вот здесь, мы не можем производить большие какие-то преобразования, но вот с такой разбивкой большого текста на переменные в принципе можно это продолжать дальше.
То есть у нас 512 + 255 получается 767, следующий шаг в 255 символов можно делать с 768 знака.
У нас же есть ещё место и дальше можно продолжать опять там делать дальше разбивку, если у вас будет очень большой текст.
Исходный код из видео
Sub main() Dim wdApp As Object Dim wdDoc As Object HomeDir$ = ThisWorkbook.Path Set wdApp = CreateObject("Word.Application") i% = 2 Do If Cells(i%, 1).Value = "" Then Exit Do If Cells(i%, 1).Value <> "" Then NPP$ = Cells(i%, 1).Text ID$ = Cells(i%, 2).Text Text$ = Cells(i%, 3).Text SN$ = Cells(i%, 4).Text DataC$ = Date FileCopy HomeDir$ + "template.doc", HomeDir$ + "" + NPP$ + "_" + ID$ + "_" + DataC$ + ".doc" Set wdDoc = wdApp.Documents.Open(HomeDir$ + "" + NPP$ + "_" + ID$ + "_" + DataC$ + ".doc") On Error GoTo ErrorHandler temp = Left(Text$, 255) temp2 = Mid(Text$, 256, 255) temp3 = Mid(Text$, 512, 255) temp4 = Mid(Text$, 768, 255) wdDoc.Range.Find.Execute FindText:="&date", ReplaceWith:=DataC$ wdDoc.Range.Find.Execute FindText:="&id", ReplaceWith:=ID$ wdDoc.Range.Find.Execute FindText:="&text", ReplaceWith:=temp wdDoc.Range.Find.Execute FindText:="&text2", ReplaceWith:=temp2 wdDoc.Range.Find.Execute FindText:="&text3", ReplaceWith:=temp3 wdDoc.Range.Find.Execute FindText:="&text4", ReplaceWith:=temp4 wdDoc.Range.Find.Execute FindText:="&sn", ReplaceWith:=SN$ wdDoc.Save wdDoc.Close End If i% = i% + 1 Loop wdApp.Quit MsgBox "Готово!" Exit Sub ErrorHandler: wdDoc.Save wdDoc.Close wdApp.Quit MsgBox "Не выполнено! " + Error End Sub
Исходный код из видео — скачать архив с файлами
ZIP архив с файлами
Смотрите видео: Исправляем ошибку VBA № 5854 слишком длинный строковый параметр в шаблоне word из таблицы excel 255 символов
Понравилась статья? Поделитесь ею с друзьями и напишите отзыв в комментариях!
I recognize that this is a year old but since the technical side of the question never got answered I figured I take the time to post this for who ever stumbles upon it.
You could do something like this of you really must do it this way.
FindAndReplace(word, replacementKey, SequentialReplaceToken);
var restOfText = replaceWithText;
while (restOfText.Length > 20)
{
var firstTwentyChars = restOfText.Substring(0, 20);
firstTwentyChars += SequentialReplaceToken;
restOfText = restOfText.Substring(20);
FindAndReplace(word, SequentialReplaceToken, firstTwentyChars);
}
FindAndReplace(word, SequentialReplaceToken, restOfText);
FindAndReplace(…) being a wrapper over the Word interop Function.
Like so:
private void FindAndReplace(Application doc, object findText, object replaceWithText)
{
//options
object matchCase = false;
object matchWholeWord = true;
object matchWildCards = false;
object matchSoundsLike = false;
object matchAllWordForms = false;
object forward = true;
object format = false;
object matchKashida = false;
object matchDiacritics = false;
object matchAlefHamza = false;
object matchControl = false;
object read_only = false;
object visible = true;
object replace = 2;
object wrap = 1;
//clear previous formatting
doc.Selection.Find.ClearFormatting();
//execute find and replace
doc.Selection.Find.Execute(ref findText, ref matchCase, ref matchWholeWord,
ref matchWildCards, ref matchSoundsLike, ref matchAllWordForms, ref forward, ref wrap, ref format, ref replaceWithText, ref replace,
ref matchKashida, ref matchDiacritics, ref matchAlefHamza, ref matchControl);
}
And SequentialReplaceToken being a string constant that is known to never come up in the document.
Для большенства организаций стандартная печатная форма трудового договора в программе 1С:Зарплата и управление персоналом не подходит. Фирма 1С, в восьмой версии своей программы, любезно предусмотрела возможность добавлять дополнительные печатные формы для документов и других объектов. Воспользуемся данной возможностью и создадим трудовой договор, который будет открываться в Microsoft Word.
Специалисты по конфигурированию могут разрабатывать внешние обработки вне конфигурации, используемой в организации. Разработанный отчет или обработка передается в виде файла так называемой внешней обработки с расширением .epf. Пользователь может подключить эту обработку к конфигурации самостоятельно.
Сведения о подключенных обработках хранятся в справочнике «Внешние обработки». Чтобы подключить новую внешнюю обработку, нужно зарегистрировать ее в указанном справочнике.
Технические требования к внешней печатной форме
Внешняя обработка должна содержать:
- Реквизит «СсылкаНаОбъект», куда при вызове будет передана ссылка на объект, для которого необходимо выполнить печать;
- Необязательный реквизит «ДополнительныеПараметры» произвольного типа, которому будут передаваться дополнительные параметры примитивного типа в виде структуры;
- Функция Печать() — без параметров, возвращающая табличный документ;
-
Также внешняя печатная обработка может иметь в своем составе макет «Параметры_Авторегистрации», используемый для автоматического заполнения принадлежности печатной формы в справочнике «Внешние обработки» и состоящий из двух колонок: «Полное имя метаданного» и «Имя табличной части».
Создание внешней обработки
Запустим 1С:Предприятие в режиме «Конфигуратор» и через меню «Файл» — «Новый» создадим внешнюю обработку.
Создадим реквизит «СсылкаНаОбъект». Для этого нажимем кнопку «Добавить» или клавишу «Insert» и заполним свойства. В зависимости от того, для каких объектов будет использоваться эта печатная форма, нужно выбрать тип. В нашем случае, внешняя печатная форма будет использоваться только для справочника «Сотрудники организации», поэтому укажем соответствующий тип «СправочникСсылка.СотрудникиОрганизаций».
Реквизит «ДополнительныеПараметры» нам не понадобится. Создадим экспортную функцию Печать() («Действия» — «Открыть модуль объекта»).
Прежде чем написать тело этой функции, создадим макет, который она будет возвращать.
Макет трудового договора в формате Microsoft Word
Существует, по меньшей мере, три способа создания шаблона.
Первый. В тексте документа содаются метки особого формата, например, «м_НомерДоговора», затем, в модуле обработки производится поиск и замена значений.
Второй способ. В документе Word создаются закладки, к которым потом можно обращаться по имени. Минус этого способа в том, что метка должна быть уникальна, т.е., например, если нужно вставить фамилию сотрудника в каждый абзац текста, то придется сделать несколько закладок с разными именами.
Способ три. В шаблон добавляются служебные поля, например, «DocVariable» или «Author». Используя DocVariable можно обращаться к переменной по имени, например, «ДокументВорд.Variables.Add(ИмяПеременной, ЗначениеПеременной);», но ее не видно в шаблоне. Поле «Author» отображается в шаблоне, но обращаться к нему придется в цикле по индексу: «ДокументВорд.Fields.item(Индекс).Result.Text = Значение;».
На мой взгляд, первый способ является самым оптимальным. Шаблон документа легко редактируется, метки видны в тексте, для создания меток не нужны сложные вставки. Поэтому будем делать шаблон именно этим способом.
Откроем программу Microsoft Office. Для примера добавим лишь одну строку: «Трудовой договор № [НомерДоговора]».
Сохраним шаблон.
Добавим получившийся шаблон в нашу обаботку. Для этого выбираем «Макеты» и нажимаем кнопку «Добавить» или клавишу «Insert».
Откроется конструктор запроса, в котором выберем тип «Active Document» и файл шаблона.
Функция Печать()
Вернемся к функции, которую мы создали ранее. Настало время написать ее тело.
// Предопределенная функция для внешних печатных форм
//
Функция Печать() Экспорт// Получим объект Microsoft Word из макета
ОбъектВорд = ПолучитьМакет(«ТрудовойДоговор»).Получить();// Получим документ из объекта и активируем его
Документ = ОбъектВорд.Application.Documents(1);
Документ.Activate();// Поиск и замена маркеров
Замена = Документ.Content.Find;
Замена.Execute(«[НомерДоговора]», , , , , , , , , «007», 2);// Вывод документа
ОбъектВорд.Application.Visible = Истина;
ОбъектВорд.Activate();
КонецФункции
// Печать()
Из кода видно, что в файле шаблона производится поиск строки «[НомерДоговора]» и ее замена на строку «007».
Параметры авторегистрации
Для автоматического заполнения принадлежности печатной формы к объектам конфигурации, добавим еще один макет «Параметры_Авторегистрации». Это будет табличный документ, содержащий одну колонку с именами объектов метаданных, к которым будет принадлежать печатная форма. В нашем случае таблица будет выглядить следующим образом.
Сохраним получившуюся внешнюю обработку.
Подключение дополнительных внешних печатных форм
Запустим 1С Предприятие. Откроем справочник «Дополнительные внешние печатные формы» через меню «Сервис» — «Дополнительные отчеты и обработки».
Нажмем кнопку «Добавить», затем зарегистрируем новую печатную форму, нажав «Заменить файл внешней обработки». Автоматически заполнится принадлежность печатной формы справочнику «Сотрудники». Выберем «Трудовой договор» в колонке «Заменяемая печатная форма» чтобы стандартная печатная форма более не использовалась.
В итоге справочник будет выглядить следующим образом.
Проверка результата
Откроем любого работающего сотрудника и нажмем кнопку «Печать» — «Трудовой договор». Откроется документ Microsoft Word с трудовым договором под номером «007».
Дальнейшее описывать не имет смысла. Думаю, не составит большого труда доработать функцию Печать() и макет договора.
Ozam 0 / 0 / 0 Регистрация: 13.03.2018 Сообщений: 14 |
||||
1 |
||||
1C 8.x 22.03.2018, 12:39. Показов 5028. Ответов 6 Метки c, word (Все метки)
Приветствую. Есть шаблон для печати и значение (в данном случае «ПолноеНаименование») имеющее более 255 символов нужно сделать так чтобы данное значение выводились в таблицу. Код предоставляю: Код шаблона Word
__________________ 0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
22.03.2018, 12:39 |
Ответы с готовыми решениями: Полное наименование товара в заявке Массив записей. Структура: наименование товара, его количество, цену за единицу товара и общую стоимость данного товара Создать тип с описанием товара: код, наименование, цена за единицу товара, количество и сумма Создать тип с описанием товара: код, наименование, цена за единицу товара, количество и сумма. Создать тип с описанием товара: код, наименование, цена за… 6 |
Тест 383 / 162 / 56 Регистрация: 26.02.2010 Сообщений: 1,241 |
|
22.03.2018, 12:55 |
2 |
А в чем собственно проблема то? 0 |
0 / 0 / 0 Регистрация: 13.03.2018 Сообщений: 14 |
|
22.03.2018, 13:01 [ТС] |
3 |
Сделать так чтобы значение имеющее более 255 символов выводилось в таблицу. Т.е. чтобы не было ошибки вроде этой: 0 |
Тест 383 / 162 / 56 Регистрация: 26.02.2010 Сообщений: 1,241 |
|
22.03.2018, 13:03 |
4 |
Ну если ворд не может вместить себя больше, то это ворд перепрогарммировать нужно? Либо обрезать на 255 символов. Либо делать 2 переменные в ворде, и в 1с разбивать на 25 символов, если он больше. а в ворде соединять эти переменные 0 |
3051 / 1998 / 524 Регистрация: 25.06.2009 Сообщений: 6,964 |
|
22.03.2018, 13:48 |
5 |
Ozam, попробуйте не через замену текста в шаблоне Word, а через создание переменных: По опыту работы с шаблонами: если можно работать с переменными в шаблоне, а не с заменой текста — лучше так и делать. 1 |
0 / 0 / 0 Регистрация: 13.03.2018 Сообщений: 14 |
|
23.03.2018, 09:30 [ТС] |
6 |
Вы можете показать какой-нибудь пример? 0 |
_ЕГОР_ Тест 383 / 162 / 56 Регистрация: 26.02.2010 Сообщений: 1,241 |
||||
23.03.2018, 09:32 |
7 |
|||
Так вот же пример
0 |
I recognize that this is a year old but since the technical side of the question never got answered I figured I take the time to post this for who ever stumbles upon it.
You could do something like this of you really must do it this way.
FindAndReplace(word, replacementKey, SequentialReplaceToken);
var restOfText = replaceWithText;
while (restOfText.Length > 20)
{
var firstTwentyChars = restOfText.Substring(0, 20);
firstTwentyChars += SequentialReplaceToken;
restOfText = restOfText.Substring(20);
FindAndReplace(word, SequentialReplaceToken, firstTwentyChars);
}
FindAndReplace(word, SequentialReplaceToken, restOfText);
FindAndReplace(…) being a wrapper over the Word interop Function.
Like so:
private void FindAndReplace(Application doc, object findText, object replaceWithText)
{
//options
object matchCase = false;
object matchWholeWord = true;
object matchWildCards = false;
object matchSoundsLike = false;
object matchAllWordForms = false;
object forward = true;
object format = false;
object matchKashida = false;
object matchDiacritics = false;
object matchAlefHamza = false;
object matchControl = false;
object read_only = false;
object visible = true;
object replace = 2;
object wrap = 1;
//clear previous formatting
doc.Selection.Find.ClearFormatting();
//execute find and replace
doc.Selection.Find.Execute(ref findText, ref matchCase, ref matchWholeWord,
ref matchWildCards, ref matchSoundsLike, ref matchAllWordForms, ref forward, ref wrap, ref format, ref replaceWithText, ref replace,
ref matchKashida, ref matchDiacritics, ref matchAlefHamza, ref matchControl);
}
And SequentialReplaceToken being a string constant that is known to never come up in the document.
I recognize that this is a year old but since the technical side of the question never got answered I figured I take the time to post this for who ever stumbles upon it.
You could do something like this of you really must do it this way.
FindAndReplace(word, replacementKey, SequentialReplaceToken);
var restOfText = replaceWithText;
while (restOfText.Length > 20)
{
var firstTwentyChars = restOfText.Substring(0, 20);
firstTwentyChars += SequentialReplaceToken;
restOfText = restOfText.Substring(20);
FindAndReplace(word, SequentialReplaceToken, firstTwentyChars);
}
FindAndReplace(word, SequentialReplaceToken, restOfText);
FindAndReplace(…) being a wrapper over the Word interop Function.
Like so:
private void FindAndReplace(Application doc, object findText, object replaceWithText)
{
//options
object matchCase = false;
object matchWholeWord = true;
object matchWildCards = false;
object matchSoundsLike = false;
object matchAllWordForms = false;
object forward = true;
object format = false;
object matchKashida = false;
object matchDiacritics = false;
object matchAlefHamza = false;
object matchControl = false;
object read_only = false;
object visible = true;
object replace = 2;
object wrap = 1;
//clear previous formatting
doc.Selection.Find.ClearFormatting();
//execute find and replace
doc.Selection.Find.Execute(ref findText, ref matchCase, ref matchWholeWord,
ref matchWildCards, ref matchSoundsLike, ref matchAllWordForms, ref forward, ref wrap, ref format, ref replaceWithText, ref replace,
ref matchKashida, ref matchDiacritics, ref matchAlefHamza, ref matchControl);
}
And SequentialReplaceToken being a string constant that is known to never come up in the document.
Сидел я крутил какие-то документы с макросами и обычный, вполне работающий макрос выпал с ошибкой:
Run-time error ‘5854’:
Слишком длинный строковый параметр
Вот срань, оказывается свойство объекта FindReplace .Find.Replacement.Text в VBA не может принимать параметры длиной больше 255 символов (привет, 70-е). А в автозаменах довольно легко упереться в эту крохотную границу. Странно, но параметр .Execute ReplaceWith: «replacementText» имеет точно такое ограничение.
Вот кусок кода, который вылетал с ошибкой, потому что citeEn (наша переменная с текстом) был слишком длинным.
With .Content.Find .Text = "#CitationPlaceholder#" .Replacement.Text = citeEn 'не больше 255 символов .Execute Replace:=wdReplaceAll End With
Гугл рекомендовал мне рекурсивно разбивать .Replacement.Text на куски по 250 символов и автозаменять друг за другом. Однако громоздкость этого решения меня напугала, поэтому я подумал что лучше бы мне искать текст, выделять его, и заменять выделенное на наш большой текст:
Selection.Find.ClearFormatting Selection.Find.Execute FindText:="#CitationPlaceholder#", Wrap:=wdFindContinue If Selection.Find.Found = True Then Selection.Text = citeEn 'много символов
Такой способ позволяет заменить как минимум 900 знаков, а дальше я не проверял.
Ярлыки: MS Word macro, VBA
Ближайшие сообщения
Похожие сообщения
Всем привет, сегодня снова работаем с эксель таблицей и шаблоном в ворд, в этом видео я вам покажу как работать с большим текстом, если у нас допустим, в нашей ячейке будет содержаться текста значительно больше чем 255 символов.
С этим вы обычной можете столкнуться при создании шаблона, для экспорта данных из эксель в ворд, при замене текста, дополнительно я покажу как исправить еще одну ошибку.
Давайте возьмём пример из первого видео, перейдете по ссылке в описании на странице есть файл в архиве.
Давайте сделаем так что у нас в заголовке таблицы будет не адрес, а текст для примера. Будем практиковаться на основе ячейки C2
.
Давайте сделаем проверку длинны текста в ячейке, используя функцию ДЛСТР — длина строки. У нас здесь сейчас находится 15 символов.
Сделаем больше текста для этого я в Microsoft Word используя функцию LOREM()
, которая сформирует случайный текст.
Теперь я скопирую текст, нужен будет блокнот, вставлю текст из буфера обмена, уберу лишние отступы переносы.
Давайте посмотрим какой длины у нас получится сейчас этот текст. Так вот у нас даже не помещается текст на экране, поправим таблицу. Длина текста в ячейке 598 символов с пробелами.
Давайте перейдём в Редактор Visual Basic, alt+f11
и посмотрим код прошлого примера.
Исправим название переменной адрес на текст, здесь исправим на текст и посмотрим что у нас получится.
Теперь откроем шаблон и заменим Адрес на Текст и исправим конструкцию для замены на &text
.
Сохраним, закроем все лишнее, совместим для наглядности эксель файл и папку для вывода ворд файлов.
Посмотрим, что теперь получится, изменю масштаб, для доступа к кнопке запуска макроса.
Появляется ошибка № 5854 — слишком длинный строковый параметр.
И хотя бланк сформировался, произошло не то что ожидалось, ID
вывели, серийный номер не изменился, потому как по коду данного макроса, мы не дошли до номера мы остановились вот здесь, ошибка произошла выше.
Давайте откроем диспетчер задач, существует проблема которую мы сейчас решим, иначе у нас при любой ошибке в работе макроса в Диспетчере задач в фоне остается запущен экземпляр Microsoft Word в котором рухнул наш шаблон.
Давайте ещё раз попробуем сформировать посмотрим, что у изменится.
Опять ошибка, и сейчас в Диспетчере задач повис Microsoft Word, его нужно закрыть и так придется делать постоянно, будем снимать задачу иначе будут появляться новые ошибки.
Давайте теперь сделаем выход из нашей функции, где мои работаем, здесь у нас создание файла проходит нормально, этот кусок у нас нормально отрабатывает.
Вставим вот здесь следующий код:
On Error GoTo ErrorHadler
Это у нас метка перехода, если произойдет ошибка, мы перейдём в конец модуля, вот здесь мы сделаем Exit Sub
— Выход из модуля.
Ниже напишем ErrorHandler:
наша метка и здесь нам нужно будет вставить код сохранения, закрытия и выхода из Word.
wdDoc.Save wdDoc.Close wdApp.Quit
Также добавим сообщение
MsgBox "Не выполнено! " + Error
Вот теперь мы избавимся проблемы, когда у нас будет зависать в Диспетчере задач Microsoft Word, который мы не успеваем закрыть.
Давайте выполним макрос, появится сообщение — не выполнено слишком длинный строковый параметр, в принципе у нас документ сформировался, но он в целом не полностью отработал.
Сейчас мы исправим эту проблему, кстати гляну в диспетчер задач у нас Microsoft Word нигде не висит, и он нам не мешает. OK.
Теперь снова перейдём в редактор VBA. и разобьем переменную Text$
на фрагменты допустимой длины.
Ну кроме исправлю маленькую опечатку, тут естественно должен быть &text
.
Дайте я посмотрю, что изменится, хотя даже если мы исправили это значение, всё равно ничего не получилось.
Теперь удалим снова бланк, вернемся вот сюда, зададим переменную temp равно Left
возьмём от переменной Text$
255 символов, снова создадим переменную temp2, воспользуемся теперь функцией Mid
, мы возьмём начиная с 256 символа текст длиной 255 символов.
Теперь нужно будет продублировать здесь строку для замены значений, укажем переменные temp
, temp2
, здесь мы сделаем заменяемое значение text2
.
Сделаем с запасом, ещё разок скопирую и вставлю
temp3 = Mid(Text$, 512, 255).
Теперь мы шагнем от 256 + 255 равно 511, начиная с 512 символа мы опять шагнем на 255 символов.
Ещё продублирую строку замены, переменная temp3
, значение text3
.
Как нам указать в шаблоне заменяемые значения? А мы их ведем просто в наш шаблон, уже есть вот эта строка &text
, мы её скопируем и вставим несколько раз, дописав числа 2 и 3.
То есть у нас всякий раз вот этот фрагмент текст будет заменяться на значения из наших переменных temp
, temp2
, temp3
. Можно в коде VBA продолжать добавлять разбивку основного текста на части, но будьте внимательны, указывая смещение и длину символов. Соответствующе правки так же вносите в шаблон.
Давайте попробуем запустить и посмотрим, что получится, закрыли, свернули.
Впишемся ли мы в данное ограничение, О’кей, готово.
Так давайте наконец посмотрим, что у нас получилось, как видите текст у нас вместился полностью, единственное хочу заметить, что между предложениями появился квадрат со знаком вопроса, но это символ переноса строк, при подготовке текста в ячейке его нужно заменить пробелом.
Следующие файлы так же сформировались, но тут у нас все осталось как обычно.
Вот таким простым способом вы можете обойти эту условность, ограничение в 255 символов, в принципе сама строковая переменная Text$ может очень много вместить в себя значений, но при работе вот этой функции FindText замена текста, вот здесь, мы не можем производить большие какие-то преобразования, но вот с такой разбивкой большого текста на переменные в принципе можно это продолжать дальше.
То есть у нас 512 + 255 получается 767, следующий шаг в 255 символов можно делать с 768 знака.
У нас же есть ещё место и дальше можно продолжать опять там делать дальше разбивку, если у вас будет очень большой текст.
Исходный код из видео
Sub main() Dim wdApp As Object Dim wdDoc As Object HomeDir$ = ThisWorkbook.Path Set wdApp = CreateObject("Word.Application") i% = 2 Do If Cells(i%, 1).Value = "" Then Exit Do If Cells(i%, 1).Value <> "" Then NPP$ = Cells(i%, 1).Text ID$ = Cells(i%, 2).Text Text$ = Cells(i%, 3).Text SN$ = Cells(i%, 4).Text DataC$ = Date FileCopy HomeDir$ + "template.doc", HomeDir$ + "" + NPP$ + "_" + ID$ + "_" + DataC$ + ".doc" Set wdDoc = wdApp.Documents.Open(HomeDir$ + "" + NPP$ + "_" + ID$ + "_" + DataC$ + ".doc") On Error GoTo ErrorHandler temp = Left(Text$, 255) temp2 = Mid(Text$, 256, 255) temp3 = Mid(Text$, 512, 255) temp4 = Mid(Text$, 768, 255) wdDoc.Range.Find.Execute FindText:="&date", ReplaceWith:=DataC$ wdDoc.Range.Find.Execute FindText:="&id", ReplaceWith:=ID$ wdDoc.Range.Find.Execute FindText:="&text", ReplaceWith:=temp wdDoc.Range.Find.Execute FindText:="&text2", ReplaceWith:=temp2 wdDoc.Range.Find.Execute FindText:="&text3", ReplaceWith:=temp3 wdDoc.Range.Find.Execute FindText:="&text4", ReplaceWith:=temp4 wdDoc.Range.Find.Execute FindText:="&sn", ReplaceWith:=SN$ wdDoc.Save wdDoc.Close End If i% = i% + 1 Loop wdApp.Quit MsgBox "Готово!" Exit Sub ErrorHandler: wdDoc.Save wdDoc.Close wdApp.Quit MsgBox "Не выполнено! " + Error End Sub
Исходный код из видео — скачать архив с файлами
ZIP архив с файлами
Смотрите видео: Исправляем ошибку VBA № 5854 слишком длинный строковый параметр в шаблоне word из таблицы excel 255 символов
Понравилась статья? Поделитесь ею с друзьями и напишите отзыв в комментариях!
Я признаю, что это год, но поскольку техническая сторона вопроса не получила ответа, я подумал, что я трачу время, чтобы опубликовать это для того, кто когда-либо натыкается на него.
Вы могли бы сделать что-то подобное, вы действительно должны сделать это таким образом.
FindAndReplace(word, replacementKey, SequentialReplaceToken);
var restOfText = replaceWithText;
while (restOfText.Length > 20)
{
var firstTwentyChars = restOfText.Substring(0, 20);
firstTwentyChars += SequentialReplaceToken;
restOfText = restOfText.Substring(20);
FindAndReplace(word, SequentialReplaceToken, firstTwentyChars);
}
FindAndReplace(word, SequentialReplaceToken, restOfText);
FindAndReplace (…) является оболочкой над функцией взаимодействия Word.
Например:
private void FindAndReplace(Application doc, object findText, object replaceWithText)
{
//options
object matchCase = false;
object matchWholeWord = true;
object matchWildCards = false;
object matchSoundsLike = false;
object matchAllWordForms = false;
object forward = true;
object format = false;
object matchKashida = false;
object matchDiacritics = false;
object matchAlefHamza = false;
object matchControl = false;
object read_only = false;
object visible = true;
object replace = 2;
object wrap = 1;
//clear previous formatting
doc.Selection.Find.ClearFormatting();
//execute find and replace
doc.Selection.Find.Execute(ref findText, ref matchCase, ref matchWholeWord,
ref matchWildCards, ref matchSoundsLike, ref matchAllWordForms, ref forward, ref wrap, ref format, ref replaceWithText, ref replace,
ref matchKashida, ref matchDiacritics, ref matchAlefHamza, ref matchControl);
}
И SequentialReplaceToken является строковой константой, которая, как известно, никогда не появляется в документе.