|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Парсинг и калькуляция в Мемо
Есть список в listBox с наименованием параметров.
типо Код:
Право Лево Вверх В низ Вперёд Назад ... Но сразу все они не используются. В Мемо может оказаться один, а других 5-10 не будет. В следующий раз наоборот. Есть мемо с кучей строк типа Код:
------ ##### ------ Право --- 15 % Лево --- 21 % Право --- 21 % Вперёд --- 0 % ------ №№№№ ------ ------******* ------ ------ №№№№ ------ Вверх --- 2 % Право --- 4 % Назад --- 0 % Лево --- 6 % В низ --- 5 % Право --- 0 % Как это дело спарсить что б в результате получилось так: Код:
------ ##### ------ Право --- 15 % Лево --- 21 % Право --- 21 % Вперёд --- 1 % ------ №№№№ ------ ------******* ------ ------ №№№№ ------ Вверх --- 2,2 % Право --- 4 % Назад --- 0 % Лево --- 6 % В низ --- 5 % Право --- 0 % ------ Итог: ----- Право --- 40 % Лево --- 27 % Вперёд --- 1 % Вверх --- 2,2 % В низ --- 5 % Тоесть что б все проценты с одинаковыми параметрами суммировались и в итог попали только параметры с положительным процентом. Проценты могут быть числом с запятой. Итог надо записать в конец мемо. Думаю надо сделать типо двух циклов. Что б первый подставлял в переменную значение строки из списка, Второй пробегал по всему Мемо и искал строки с этим значением. Если б делал одно значение, было б типа такого: Код:
{################## Функция парсинга ################} function Pars(T_, ForS, _T: string): string; var a, b:integer; begin Result := ''; if (T_='') or (ForS='') or (_T='') then Exit; a:=Pos(T_, ForS); if a=0 then Exit else a:=a+Length(T_); ForS:=Copy(ForS, a, Length(ForS)-a+1); b:=Pos(_T, ForS); if b>0 then Result:=Copy(ForS, 1, b - 1); end; {----------------------------------------------------} procedure TForm1.Button1Click(Sender: TObject); var I:integer; S: string; bonus1:real; // Право begin S:=memo1.Text; For I:=0 to Memo1.Lines.Count-1 do begin If pos('Право --- ',S)<>0 then Begin bonus1:=bonus1+StrToFloat(pars('Право ---', s, ' %')); End; End; memo1.lines.Add(''); memo1.lines.Add('--- Итог: ---'); memo1.lines.Add(''); memo1.lines.Add('Право --- '+ FloatToStr(bonus1)+' %'); end; Но в listBox 30 значений лежит. Можно конечно 30 проверок налепить, но хочется по нормальному сделать в цикле. Наверно надо как то через два цикла делать. Что б первый подставлял из listBox значения, а второй пробегался по всему Мемо и парсил то что нужно. Что б вместо Код:
... If pos('Право --- ',S)<>0 then ... Код:
... If pos(listBox1.Items.Strings[b]+' --- ',S)<>0 then ... И ещё вопрос: Есть несколько переменных, a1, a1, a2, a3, a4, a5:string; можно ли им присваивать индексы в цикле ? что б типа такого получилось: Var i:integer; a1, a1, a2, a3, a4, a5:string; Begin For i:=0 to Memo1.Lines.Count-1 do begin If pos('123',Memo1.Lines.Strings[i])<>0 then Begin a[i]:=Memo1.Lines.Strings[i]; end; end; end; Спасибо. Последний раз редактировалось TEKTON, 26.07.2018 в 21:41. |
#2
|
|||
|
|||
Заводишь массив для подсчета значения параметра.
Далее ползешь по мемо, для каждой строки выделяешь нужный параметр и суммируешь в массиве. Далее просто вывод. Как-то так: Код:
var P : Array Of Double; I, pIdx : Integer; pName : String; pVal : Double; begin SetLength(P,ListBox1.Items.Count); For I := Low(P) To High(P) Do P[i] := 0; // just in case For I := 0 To Memo1.Lines.Count-1 Do Begin ExtractParamNameFromLine(Memo1.Lines[i],pName,pVal); If pName <> '' Then Begin pIdx := ListBox1.Items.IndexOf(pName); If pIdx > -1 Then P[pIdx] := P[pIdx] + pVal; End; End; // Print to memo Memo1.Lines.Add('--- Итог: ---'); For I := Low(P) To High(P) Do If P[i] > 0 Then Memo1.Lines.Add(ListBox1.Items[i] + ' --- '+ FloatToStr(P[i]) + ' %'); end; Ну, процедуру ExtractParamNameFromLine думаю сам напишешь. Декларация: Код:
procedure ExtractParamNameFromLine(S : String; var AName : String; var AVal : Double); Последний раз редактировалось lmikle, 27.07.2018 в 01:45. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
TEKTON (26.07.2018)
|
#3
|
||||
|
||||
lmikle, спасибо.
Цитата:
Чёт я буксую с этой procedure ExtractParamNameFromLine В первом цикле получаем длинну ListBox Во втором пробегаем по Memo ExtractParamNameFromLine - Парсит название параметра и % Если параметр (pName) не равен нулю, тогда записываем в pIdx номер строки ListBox Далее в масив P заносим номер строки и % Потом в конце это дело записываем в конец Мемо Цитата:
Цитата:
Цитата:
Что передавать этой проуедуре ExtractParamNameFromLine (вроде у неё всё есть) Или что в теле её обрабатывать не догоняю. Последний раз редактировалось TEKTON, 27.07.2018 в 00:53. |
#4
|
|||
|
|||
Да ЯТЬ!
Ну просто же. Код:
procedure ExtractParamNameFromLine(S : String; var AName : String; var AVal : Double); var sVal : String; begin AName := ''; AVal := 0; If Pos('---',S) > 0 Then Begin Try AName := Trim(Copy(S,1,Pos('---',S)-1)); sVal := Trim(Copy(S,Pos('---',S)+3,Pos('%',S)-Pos('---',S)-3)); AVal := StrToFloat(sVal); Except // Нехорошо прятать эксепшены, но лень вспоминать как tryStrToFloat работает End End; end; Как-то так. Если ничего не напутал, то должно работать. ЗЫ. Я там основной исходник тоже поправил чуть-чуть. Последний раз редактировалось lmikle, 27.07.2018 в 01:46. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
TEKTON (27.07.2018)
|
#5
|
|||
|
|||
Цитата:
Проверил, всё работает чётенько вроде! Надо наверно в одном посте соединить два кусочка кода. Пригодится ещё кому нить Код:
{-------------------------- ФУНКЦИЯ --------------------------------} procedure ExtractParamNameFromLine(S : String; var AName : String; var AVal : Double); // Закодил lmikle http://www.delphisources.ru var sVal : String; begin AName := ''; AVal := 0; If Pos('---',S) > 0 Then Begin Try AName := Trim(Copy(S,1,Pos('---',S)-1)); sVal := Trim(Copy(S,Pos('---',S)+3,Pos('%',S)-Pos('---',S)-3)); AVal := StrToFloat(sVal); Except // Нехорошо прятать эксепшены, но лень вспоминать как tryStrToFloat работает End End; end; {------------------------- ЮЗАЕМ -----------------------------} procedure TForm1.Button1Click(Sender: TObject); var P : Array Of Double; I, pIdx : Integer; pName : String; pVal : Double; begin SetLength(P,ListBox1.Items.Count); For I := Low(P) To High(P) Do P[i] := 0; // just in case For I := 0 To Memo1.Lines.Count-1 Do Begin ExtractParamNameFromLine(Memo1.Lines[i],pName,pVal); If pName <> '' Then Begin pIdx := ListBox1.Items.IndexOf(pName); If pIdx > -1 Then P[pIdx] := P[pIdx] + pVal; End; End; // Print to memo Memo1.Lines.Add(''); Memo1.Lines.Add('--- Итоговый подсчёт: ---'); Memo1.Lines.Add(''); For I := Low(P) To High(P) Do If P[i] > 0 Then Memo1.Lines.Add(ListBox1.Items[i] + ' --- '+ FloatToStr(P[i]) + ' %'); end; Последний раз редактировалось TEKTON, 27.07.2018 в 04:55. |
#6
|
|||
|
|||
Цитата:
Как раз пригодилось!!!! Спс) |