Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.10.2022, 02:46   #1
cybernewbie
Пользователь
 
Регистрация: 01.10.2022
Сообщений: 63
По умолчанию Поиск по наименованию и суммирование (Memo)

Здравствуйте,

Возможно неверно указал заголовок, нужно вот что.
Имеется следующий текст в Memo:
Код:
class: 1234
buf: 2323
prod:
 name: msi 990
 col: red
 quantity: 1
prod:
 name: micro 500
 col: blue
 quantity: 1
prod:
 name: msi 990
 col: red
 quantity: 2
prod:
 name: allso
 col: blue
 quantity: 1
prod:
 name: micro 500
 col: blue
 quantity: 1
book: open
TF: open
Нужно привести его к такому виду:
Код:
class: 1234
buf: 2323
prod:
 name: msi 990
 col: red
 quantity: 3
prod:
 name: micro 500
 col: blue
 quantity: 2
prod:
 name: allso
 col: blue
 quantity: 1
book: open
TF: open
Помогите пожалуйста, заранее благодарю Вас.
cybernewbie вне форума Ответить с цитированием
Старый 09.10.2022, 17:12   #2
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,550
По умолчанию

Считать Memo в массив строк, сделать что надо - и обратно в Memo, предварительно его очистив.
digitalis вне форума Ответить с цитированием
Старый 09.10.2022, 18:42   #3
cybernewbie
Пользователь
 
Регистрация: 01.10.2022
Сообщений: 63
По умолчанию

Цитата:
Сообщение от digitalis Посмотреть сообщение
сделать что надо
С этим у меня проблемы, а точнее не могу построить логику поиска, и подсчёта по родительским строкам..
Код:
procedure TForm1.Button1Click(Sender: TObject);
const
S=100; // размер массива var
var
a:array[0..S]of string[255]; //массив
n: integer; // количество строк, введенных в поле Memo
i:integer; // индекс элемента массива
st:string;
begin
n:=Memo1.Lines.Count;
 if n = 0 then begin
 ShowMessage('Нет данных!');
 Exit; // выход из процедуры обработки события
 end;
 if n > S then begin
 ShowMessage('Количество строк превышает размер массива.');
 n:=S;
 end;
for i:=1 to n do
a[i]:=Form1.Memo1.Lines[i-1];
Memo1.Clear;
 if n > 0 then begin
 st:='Введенный массив:'+#13;
  for i:=1 to n do begin
  st:=st+a[i]+#13;
  Memo1.lines.Add(a[i]);
  end;
 ShowMessage(st);
 end;
end;
cybernewbie вне форума Ответить с цитированием
Старый 09.10.2022, 19:04   #4
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

С полем Memo.Lines можно работать как с массивом. Вы можете в массиве собирать сразу конечный результат, а не загружать в него исходные данные. После очищаете Memo.Lines.Clear и переносите строки из массива в Memo через Memo.Lines.Add

Для реализации подсчета стоит завести динамический список, а не массив. Так будет проще собрать одинаковые записи в кучу.

Последний раз редактировалось macomics; 09.10.2022 в 19:26.
macomics вне форума Ответить с цитированием
Старый 10.10.2022, 01:12   #5
cybernewbie
Пользователь
 
Регистрация: 01.10.2022
Сообщений: 63
По умолчанию

Что то у меня пока не получается, сейчас я вывожу в список так, т.е. всё что найду:
Код:
type
  TPCount = ^TCount; //указатель на тип TCount

  TCount = record
    name1: string;
    name2: string;
    name3: string;
    next: TPCount; // следующий элемент списка
  end;

var
  head: TPCount; // начало (голова) списка



procedure TForm1.Button1Click(Sender: TObject);
var
  curr: TPCount; // новый элемент списка
  i,n:integer;
  st:string;
begin
  //new(curr); // выделить память для элемента списка

  for i:=0 to memo1.Lines.Count-1 do
  begin
  new(curr);
   if LeftStr(memo1.Lines.Strings[i], 6)=' name:' then
   curr^.name1 := memo1.Lines.Strings[i];
   if LeftStr(memo1.Lines.Strings[i], 5)=' col:' then
   curr^.name2 := memo1.Lines.Strings[i];
   if LeftStr(memo1.Lines.Strings[i], 10)=' quantity:' then
   curr^.name3 := memo1.Lines.Strings[i];
   curr^.next := head;
   head := curr;
  end;

  n := 0;
  st := '';
  curr := head; // указатель на первый элемент списка
  while curr <> nil do
  begin
    n := n + 1;
    st := st + curr^.name1 + #13 + curr^.name2 + #13 + curr^.name3;
    curr := curr^.next; // указатель на следующий элемент
  end;

  if n <> 0
    then ShowMessage('Список:' + #13 + st)
  else ShowMessage('В списке нет элементов.');
end;
Как мне вести подсчёт? цикл в цикле? и как потом это всё собрать воедино... у меня в голове всё смешалось... завтра ещё попробую
cybernewbie вне форума Ответить с цитированием
Старый 10.10.2022, 02:35   #6
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,872
По умолчанию

Цитата:
Сообщение от cybernewbie Посмотреть сообщение
type
TPCount = ^TCount; //указатель на тип TCount

TCount = record
name1: string;
name2: string;
name3: string;
next: TPCount; // следующий элемент списка
end;
Это не тот список. Это список времен Турбо Паскаля / Царя Гороха.
northener вне форума Ответить с цитированием
Старый 10.10.2022, 07:26   #7
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
Это не тот список. Это список времен Турбо Паскаля / Царя Гороха.
northener, научи же новичка как по твоему надо.

cybernewbie, ошибка в том, что вы в списке не ассоциируете 4 строки с одной записью. Когда нашли строку prod: вам надо следующие 3 строки загнать в одну структуру и желательно упорядочить (если они могут идти в произвольном порядке). При добавлении новой записи в список надо сделать еще кое-что. Проверить все уже имеющиеся данные в списке на предмет совпадения с новой записью и при совпадении сложить числа в поле quantity, а не добавлять новую запись в список.
macomics вне форума Ответить с цитированием
Старый 10.10.2022, 11:17   #8
cybernewbie
Пользователь
 
Регистрация: 01.10.2022
Сообщений: 63
По умолчанию

Цитата:
Сообщение от macomics Посмотреть сообщение
cybernewbie, ошибка в том, что вы в списке не ассоциируете 4 строки с одной записью. Когда нашли строку prod: вам надо следующие 3 строки загнать в одну структуру и желательно упорядочить (если они могут идти в произвольном порядке). При добавлении новой записи в список надо сделать еще кое-что. Проверить все уже имеющиеся данные в списке на предмет совпадения с новой записью и при совпадении сложить числа в поле quantity, а не добавлять новую запись в список.
Спасибо, стало понятней, сейчас буду пробовать
cybernewbie вне форума Ответить с цитированием
Старый 10.10.2022, 15:59   #9
cybernewbie
Пользователь
 
Регистрация: 01.10.2022
Сообщений: 63
По умолчанию

Теперь считает:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  curr: TPCount; // новый элемент списка
  i,a,b,n:integer;
  st:string;
begin
  //new(curr); // выделить память для элемента списка

  for i:=0 to memo1.Lines.Count-1 do begin
  new(curr);
   if LeftStr(memo1.Lines.Strings[i], 5)='prod:' then begin
   curr^.name1 := memo1.Lines.Strings[i];
   curr^.name2 := memo1.Lines.Strings[i+1];
   curr^.name3 := memo1.Lines.Strings[i+2];
   curr^.name4 := memo1.Lines.Strings[i+3];
   b:=i+4;
    for a:=b to memo1.Lines.Count-1 do begin
     if (memo1.Lines.Strings[a+1]=curr^.name2) and (LeftStr(memo1.Lines.Strings[a+3], 10)=' quantity:') then begin
     curr^.name4:=' quantity: ' + inttostr((strtoint(StringReplace(curr^.name4,' quantity: ','',[rfReplaceAll])) + strtoint(StringReplace(memo1.Lines.Strings[a+3],' quantity: ','',[rfReplaceAll]))));


     end;
    end;
   curr^.next := head;
   head := curr;

  end;
  end;

  n := 0;
  st := '';
  curr := head; // указатель на первый элемент списка
  while curr <> nil do
  begin
    n := n + 1;
    st := st + #13 + curr^.name1 + #13 + curr^.name2 + #13 + curr^.name3 + #13 + curr^.name4;
    curr := curr^.next; // указатель на следующий элемент
  end;

  if n <> 0
    then ShowMessage('Список:' + #13 + st)
  else ShowMessage('В списке нет элементов.');

end;
Но после подсчёта считает и повторяющиеся записи, и формирует список снизу-верх.. не могу понять как сделать проверку на то, чтобы он проверял список, и не добавлял запись если она есть в списке..
Изображения
Тип файла: png Screenshot_1.png (7.7 Кб, 20 просмотров)
cybernewbie вне форума Ответить с цитированием
Старый 10.10.2022, 16:01   #10
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Использовать Delete на каждой посчитанной записи. Тогда и циклы надо будет проходить от конца к началу
macomics вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск совпадений и их суммирование Антониовсс Microsoft Office Excel 3 13.02.2017 19:47
Хранение и поиск значения по строковому наименованию igh0st Общие вопросы Delphi 7 23.09.2013 11:19
Поиск и суммирование информации manula Microsoft Office Excel 6 07.05.2013 14:24
Поиск цены товара по дате и наименованию dronicos Microsoft Office Excel 4 02.11.2012 19:31
Поиск дублей и суммирование Dicata Microsoft Office Excel 3 16.01.2012 12:29