Помощь - Поиск - Пользователи - Календарь
Полная версия: вычисляемое поле - ''?''
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Делфи
1147
В Dbgride есть столбцы, в в ячейках которых через запятую перечислены некоторые номера (например 56, 9,23,18). Столбец 1 и столбец 2. Данных в ячейках первого столбца всегода больши или равно ячейке воторого столбца. Нельзя ли сделать так чтобы количество номеров второго столбца вычиталось из первого? К примеру в одной из ячеек первого столбца содержится через запятую 7 элементов, во второй мы помещаем 5 элементов, и соответствующая ячейка третьего столбца нам показывает цифру 2?
Может вычисляемые поля Dbgrida подойдут? хотя у меня ничего не получилось с этим вариантом
Client
Цитата
7 элементов, во второй мы помещаем 5 элементов, и соответствующая ячейка третьего столбца нам показывает цифру 2
Тут не понятно, давай пример точнее
1147
1й столбец. в одной из ячеек через запятую находятся 7 элементов: 45,78,2,908,54м,22,111а
2й столбец. в соседнюю ячейку (слева находятся 45,78,2,908,54м,22,111а) записываем 5 элементов: 55,23,568,4а,33. Сохраняем (нажимаем Enter)
3й столбец выдает разность первого и второго столбца, т.е. 2 (7 элементов ячейки первого столбца минус 5 элементов соседней ячейки второго столбца)
Client
Должно быть (45+78+2+908+54+22+111) - (55+23+568+4+33) =1220-679=541
Так?
volvo
Цитата
Нельзя ли сделать так чтобы количество номеров второго столбца вычиталось из первого?
Можно... Итак:

1) находим в Object Inspector-е источник данных для твоего DBGrid-а. Допустим, ADOTable2...
Нажмите для просмотра прикрепленного файла

2) щелкаем правой кнопкой мыши, выбираем NewField, и заполняем все необходимые данные (обязательно выставить Calculated, а не то, что предлагается для таблицы по умолчанию !!!):
Нажмите для просмотра прикрепленного файла
, после чего в ДБГриде должен появиться еще один столбец...

3) для этой же самой таблицы находим событие OnCalcField:
Нажмите для просмотра прикрепленного файла
и пишем для него обработчик:
procedure TForm1.ADOTable2CalcFields(DataSet: TDataSet);

// WideString - потому что такой тип у ADOTable2first.Value и у ADOTable2second.Value
function Counter(ws: WideString): integer;
var i: integer;
begin
result := 0;
for i := 1 to Length(ws) do
if ws[i] = ',' then Inc(result);
end;

begin
ADOTable2Y.Value := Counter(ADOTable2first.Value) - Counter(ADOTable2second.Value); // <--- Вот оно !!!
end;
Если такой алгоритм подсчета не нравится - реализуй любой другой, главное - чтоб ADOTable2Y.Value на выходе из процедуры содержало то, что тебе надо...

4) Все, спасибо за внимание, запускаешь и проверяешь...
1147
Строка так должна выглядеть?
ADOTable2WideStringField1.Value := Counter(ADOTable2WideStringField3.Value) - Counter(ADOTable2WideStringField6.Value);

Вроде бы все верно, но появляется ошибка-несовместимые типы: widestring and integer
volvo
Во втором пункте (описанном мной) ты какой тип поля видишь на скриншоте? Зачем же добавил WideString? А если тебе надо именно WideString, то приводи к нему:

ADOTable2WideStringField1.Value := 
IntToStr(Counter(ADOTable2WideStringField3.Value) - Counter(ADOTable2WideStringField6.Value));
1147
И правда! Сделал по-новому-получилось. Но, как написано в пункте 2 - выставить calculated, все сделал. Вот только тип поменял на integer, а не нужно было..
Алгоритм подсчета чудесный, мне казалось реализация такой процедуры будет намного сложней!
Остается только в очередной раз поблагодарить автора за четкие, действенные советы good.gif
1147
Хотелось бы уточнить еще 1 момент: когда в столбце ADOTable2WideStringField6 ничего нет, а в ADOTable2WideStringField3 данные уже заполнены, через запятую стоят 3 элемента, то в результирующем столбце ADOTable2WideStringField3 оказывается 2. Получается что в пустом втором столбце вместо нуля элементов считается что есть один
Сколько бы элементов не находилось в первом столбце, если во втором при этом ничего нету, в результирующем, находится значение первого столбца, уменьшенного на единицу. Почему из первого столбца вычитается 1 вместо 0?
volvo
Цитата
Почему из первого столбца вычитается 1 вместо 0?
А кто тебе сказал, что Counter для первого столбца равен количеству чисел? Вообще-то там количество запятых считается, чисел всегда на 1 больше (если у тебя сколько-то элементов разделены 5-ю запятыми, то это не сколько-то, а 6, правда?)... Как вариант,
  function Counter(ws: WideString): integer;
var i: integer;
begin
if ws = '' then result := 0
else begin
result := 1;
for i := 1 to Length(ws) do
if ws[i] = ',' then Inc(result);
end;
end;
? Что заставит функцию Counter возвращать именно количество элементов, а не разделяющих запятых, тогда будет работать корректно и при пустых строках...
1147
Вот теперь все как надо. Еще раз спасибо!
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.