Консультация № 183004
30.04.2011, 13:30
175.29 руб.
0 28 1
Добрый день. Прошу помощи в следующем вопросе: У меня в программе формируется бланк, выходной формат по условиям должен быть в Excel.
В документ кроме цифр переносится текст. Вот с переносом текста у меня возникли проблемы.
Переношу текст из программы в Excel таким образом
Код:
  for i:=1 to length(mem3) do begin
j:=(i div 105) + 7;
Ex.ActiveWorkBook.WorkSheets[L3].Cells[j,2].value:=Ex.ActiveWorkBook.WorkSheets[L3].Cells[j,2].value+mem3[i];

Текст берется из Мемо (mem3) и пишется в открытую книгу Ex.ActiveWorkBook
Проблема с том что при переносе текста слова переносятся как угодно. Обрезается слово в любом месте (Авт-омобиль, Автомобил-ь).
То есть по коду все правильно, 105 знаков и перенос. Но хочется что бы еще и граматика не страдала, и перенос правильно работал.
Подскажите как правильно реализовать!

Обсуждение

Неизвестный
30.04.2011, 17:47
общий
Адресаты:
А почему именно 105 знаков. Ведь если применять еще и грамматику, то получится то 104 символа, то 106 символов.
давно
Посетитель
352040
133
30.04.2011, 19:04
общий
30.04.2011, 20:57
105 в одну строку умещается. Вот и спрашиваю как исхитрится и грамматику и перенос?! Таже 1С делает документы в экселе, значит можно. Я даже не пойму в какую сторону копать. перенос работает, а вот с грамматикой хромет, очень сильно. Может какой хитрый массив придумать? Вот и прошу совета и помощи!
Об авторе:
Пользуюсь Delphi Enterprise Version7.
давно
Мастер-Эксперт
425
4118
01.05.2011, 04:45
общий
Адресаты:
Уточните, пожалуйста - Вам нужно сделать перенос слова или перенос в слове?
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
352040
133
01.05.2011, 06:04
общий
Пожалуй будет достаточно перенос целого слова. Думаю с переносом в слове будет сложнее.
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
01.05.2011, 09:45
общий
Адресаты:
А почему бы Вам не организовать перенос в Excel из Memo построчно.
Как-то так:

for i:=0 to Memo1.Lines.Count-1 do
begin
Ex.ActiveWorkBook.WorkSheets[L3].Cells[i+8, 2].value:= memo1.Lines[i];
end;

давно
Посетитель
352040
133
01.05.2011, 10:19
общий
01.05.2011, 10:31
Я пробовал таким образом. Сейчас вспомнил. Тут есть нюанс. Он переносит текст как положено, но у меня в мемо, в одну строку входит больше 105 символов. И соответсвенно в эксель при выгрузке 105 символов видно, а отсальные выходят за границу листа. Если ограничить ввод 105-ю символами в одну строку, то в принципе устроит Ваш вариант. MaxLength ограничивает ввод на все мемо. Как сделать ограничение на строку? Думаю при таком варианте будет нормально работать перенос.
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
01.05.2011, 10:56
общий
Адресаты:
Могу предложить такой вариант:
Ослеживание изменений строки Memo
Процедуру привязываем к событию Memo OnChange

procedure TForm1.Memo1Change(Sender: TObject);
var
s: string;

begin
s:= RightStr(Memo1.Lines[Memo1.Lines.count - 1], 1);
edit1.Text:= IntToStr(length(Memo1.Lines[Memo1.Lines.count - 1]));
if (s = ' ') and (length(Memo1.Lines[Memo1.Lines.count - 1]) > 90) then // если длина текущей строки > 90 и текущий символ пробел, то добавляем строку
begin
Memo1.Lines[Memo1.Lines.count - 1]:= leftstr(Memo1.Lines[Memo1.Lines.count - 1], Length(Memo1.Lines[Memo1.Lines.count - 1]) - 1);
Memo1.Lines.Add(' ');
end;

end;
Неизвестный
01.05.2011, 10:59
общий
Адресаты:
В Edit1 вывел значение текущего количества символов для отладки и контроля.
Можно потом убрать.
давно
Посетитель
352040
133
01.05.2011, 11:50
общий
Вы знаете это возможно и выход из положения. По крайней мере на тестовой сработало. Попробую привязать к своей программе. Постараюсь в течение дня. Еще и работать надо.
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
01.05.2011, 12:11
общий
Адресаты:
Могу ли я свои посты объединить и оформить в виде ответа? Способствует ли они решению поставленной в вопросе задаче?
давно
Посетитель
352040
133
01.05.2011, 12:59
общий
Объединил Ваши советы. Все получилось как нужно. Если вводить вручную, то просто замечательно. А вот когда вставляешь из буфера текст, не хочет обрезатся и переносится. И вот НОВЫЙ вопрос по этой теме. Можно ли заставить делать перенос при вставке текста? А посты конечно можно объединить и оформить в виде ответа. Надеюсь кому то понадобится такой совет.
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
01.05.2011, 13:04
общий
Адресаты:
Думаю, можно. Сейчас попробую.
Неизвестный
01.05.2011, 13:47
общий
это ответ
Здравствуйте, Владимир!
В итоге обсуждения предлагается вариант решения задачи:
1. Перенос из Memo в Excel производить построчно
2. Определить процедуру разбивки текста в Memo на строки при превышении 90 символов при ручном вводе
3. Определить процедуру разбивки текста в Memo на строки при превышении 90 символов при вставке текста из буфера обмена.

Исходные тексты процедур размещаю в приложении

Приложение:
1. Часть процедуры переноса в Excel:
...
for i:=0 to Memo1.Lines.Count-1 do
begin
Ex.ActiveWorkBook.WorkSheets[L3].Cells[i+8, 2].value:= memo1.Lines[i];
end;
...
2. Процедура ручного ввода в Memo
procedure TForm1.Memo1Change(Sender: TObject);
var
s: string;

begin
s:= RightStr(Memo1.Lines[Memo1.Lines.count - 1], 1);
edit1.Text:= IntToStr(length(Memo1.Lines[Memo1.Lines.count - 1]));
if (s = ' ') and (length(Memo1.Lines[Memo1.Lines.count - 1]) > 90) then
begin
Memo1.Lines[Memo1.Lines.count - 1]:= leftstr(Memo1.Lines[Memo1.Lines.count - 1], Length(Memo1.Lines[Memo1.Lines.count - 1]) - 1);
Memo1.Lines.Add(' ');
end;
end;

3. Процедура вставки текста из буфера обмена.
При вставке текста он разбивается по строкам.

procedure TForm1.Button2Click(Sender: TObject);
var
i, j: integer;
str_list: TMemo;
s, s_right: string;

begin
Memo1.Clear;
str_list:= TMemo.Create(Form1); // формируем динамический невидимый объект
str_list.Visible:= False;
str_list.Parent:= Form1;
str_list.PasteFromClipboard;
for i:=0 to str_list.Lines.Count do
begin
for j:= 1 to Length(str_list.Lines[i]) do // посимвольно переносим в основной элемент Memo и применяем алгоритм разбивки по строкам
begin
s:= str_list.Lines[i][j];
Memo1.Text:= Memo1.Text + s;
s_right:= RightStr(Memo1.Lines[Memo1.Lines.count - 1], 1);
edit1.Text:= IntToStr(length(Memo1.Lines[Memo1.Lines.count - 1]));
if (s_right = ' ') and (length(Memo1.Lines[Memo1.Lines.count - 1]) > 90) then
begin
Memo1.Lines[Memo1.Lines.count - 1]:= leftstr(Memo1.Lines[Memo1.Lines.count - 1], Length(Memo1.Lines[Memo1.Lines.count - 1]) - 1);
Memo1.Lines.Add(' ');
end;
end;
end;
str_list.Clear; // очищаем динамический элемент
str_list.Free; // освобождаем память
end;
5
Оперативный и полный ответ! Большое СПАСИБО!!!
Неизвестный
01.05.2011, 13:49
общий
Адресаты:
Сформировал ответ.
В приложении к ответу написал процедуру вставки из буфера обмена и разбивки по строкам.
Если по ней возникнут вопросы - пишите в форум.
давно
Посетитель
352040
133
01.05.2011, 16:28
общий
Еще раз хочу поблагодарить за оперативную и полную консультацию. Реализовал в своем приложении. Работает прекрасно!!!
Большое спасибо!!!
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
01.05.2011, 16:55
общий
Адресаты:
Спасибо!
Всегда рад помочь коллегам, поделиться своими знаниями.
давно
Посетитель
352040
133
02.05.2011, 19:40
общий
Добрый вечер. Вопрос возник по переносу в Excel. Перенос в Memo работает прекрасно. Все фунции что описаны в посте работаю хорошо. Но опять споткнулся об Excel. Переносит по линиям Memo Memo1.Lines.count - 1 и если в мемо пробелы он их тоже считает и переносит.

if (s_right = ' ') and (length(Memo1.Lines[Memo1.Lines.count - 1]) > 90) then

Вопрос! Как сказать программе что бы остальное не переносить. Memo шире чем 90 знаков. По коду, как 90 знаков, так перенос. А на Memo1.Lines 0 к примеру еще осталось 10 или 5 пробелов. И программа естественно при выгрузке все пробелы считает и переносит. У меня в Excele после выгрузке получается не 10 строк а 60. Практически четверостишье!
Написал много. А не понятно. Объяснения в приложении. Там и мемо и эксель.
Подскажите как этого избежать!
Прикрепленные файлы:
14638a87fbe2d927a5bd624029caa90d.jpg
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
02.05.2011, 20:02
общий
Адресаты:
А каким кодом Вы переносите в Excel? Может целиком построчно и переносить?
давно
Посетитель
352040
133
02.05.2011, 20:16
общий
Приношу свои ИЗВИНЕНИЯ!!!
Я увдекся мемо и забыл про перенос в Эксель.
У меня остался старый код
Код:
for i:=1 to length(mem3) do begin
j:=(i div 105) + 7;
Ex.ActiveWorkBook.WorkSheets[L3].Cells[j,2].value:=Ex.ActiveWorkBook.WorkSheets[L3].Cells[j,2].value+mem3[i];


Исправил на то что посоветовали Вы, и все заработало как нужно.
Код:
for i:=0 to Memo1.Lines.Count-1 do
begin
Ex.ActiveWorkBook.WorkSheets[L3].Cells[i+8, 2].value:= memo1.Lines[i];
end;

Еще раз благодарю за помощь и быстрый ответ!!!
И еще за то что напомнили-НУЖНО БЫТЬ ВНИМАТЕЛЬНЕЙ!!!
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
02.05.2011, 20:55
общий
Адресаты:
Ничего, бывает и такое. Удачи.
давно
Посетитель
352040
133
02.05.2011, 21:02
общий
Тем не менее стыдно. Вы подсказали, рассказали, объяснили. А я опять на те же грабли
Об авторе:
Пользуюсь Delphi Enterprise Version7.
давно
Посетитель
352040
133
02.05.2011, 21:09
общий
Если можно, я еще напишу. У меня процесс доходит до конечного пользователя. Думаю в течении нескольких дней превлечь некоторых пользователей для тестирования. Вдруг вопросы возникнут.
Хотя один вопрос уже есть.
Но думаю, следующий вопрос мы отнесем к другой теме.
Скажу лишь задумку следующего вопроса.
У нас на предприятии есть локальная сеть (хотя где её сейчас нет). Хочу сделать что бы программа сама следила за обновлениями. Все равно будут ляпы в коде, предется обновлять. Вот сама пусть и смотрит за обновлениями, как выложили на расшаренный ресурс новую версию, сообщи пользователю. А вот как реализовать, не знаю.

P.S. Вот и новый вопрос возник!
В другой пост!!!
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
03.05.2011, 08:04
общий
Адресаты:
Так а в чем проблема? Пусть пользователи и запускают программу из расшаренного ресурса. Вы на нем только и будете обновлять.
Только в коде нужно прописать локальные папки пользователя. Т.е. программу он запускает из сети, а документы формируются у него на компьютере.
По крайней мере в течение 3 лет в своей практике я использую такой принцип.
давно
Посетитель
352040
133
03.05.2011, 08:17
общий
Хм. Что то я такой вариант упустил. Так и сделаю.
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Неизвестный
03.05.2011, 08:25
общий
03.05.2011, 08:48
В виде совета: перед записью новой версии, делайте копию предыдущего исполняемого файла в виде file_copy.exe.
Бывают случаи возврата к старой версии.
давно
Посетитель
352040
133
03.05.2011, 08:47
общий
Бывае такое, согласен. Благодарю за дельные советы.
Об авторе:
Пользуюсь Delphi Enterprise Version7.
давно
Мастер-Эксперт
425
4118
03.05.2011, 08:57
общий
Адресаты:
И не забудьте для всех пользователей в расшареной папке (кроме Вас, разумеется ), выставить на программу права только на чтение.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
352040
133
03.05.2011, 09:16
общий
Ну это понятно.
Об авторе:
Пользуюсь Delphi Enterprise Version7.
Форма ответа