Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

DBGrid

9.1K
13 марта 2006 года
sasha_san
24 / / 01.02.2006
Hi there,
мое первое сообщение не сохранилось на форуме - интересно почему? Или его кто-то удалил?
Посему, по второму разу.
1) надо подсчитать обычную сумму во всех полях DBGrida, однако этот вот код почему-то не работает

long int a;
[COLOR=blue]
Table2->First();
while(!Table2->Eof)
{
a = Table1->FieldByName("Paid")->AsInteger;
a = a + a;
Table2->Next();
}
Table2->First();
StaticTotal->Caption = IntToStr(a);
[/COLOR]
2) вопрос по вложению ф-ций - есть скажем набор операторов, которые должны выполняться довольно часто. Я их объединяю в одну ф-цию. Однако при клике на какой-то кнопке таких ф-ций довольно много, и часть из них повторяется, потому возникает идея их объединить в ф-цию тоже. Вопрос - насколько эффективно такое вложение функций? То есть, каков предел, и самое главное, будет ли от этого работать быстрее программа?
263
13 марта 2006 года
koltaviy
816 / / 16.12.2004
2) Предела нет. Программа быстрее работать не будет. Ты можешь объединить операторы в функции для краткости написания и удобности чтения кода..
Так что при таком объединении ты ускоришь не время работы программы, а свое рабочее время..
10
13 марта 2006 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by sasha_san
Вопрос - насколько эффективно такое вложение функций?


Эффективность проявляется в следующем: если в одной из функций есть баг, достаточно его исправить в ней, и больше он повторяться не будет. Если же код растворен в теле программы, выловить все ошибки будет очень трудно.

9.1K
13 марта 2006 года
sasha_san
24 / / 01.02.2006
Цитата:
Originally posted by Freeman
Эффективность проявляется в следующем: если в одной из функций есть баг, достаточно его исправить в ней, и больше он повторяться не будет. Если же код растворен в теле программы, выловить все ошибки будет очень трудно.



Спасибо, а как несчет первого? :P
И кстати, по поводу второго - я имел в виду не операторы, из которых составляются функции, а функции, из которых составляются функции, причем в многоярусном варианте...

294
14 марта 2006 года
Plisteron
982 / / 29.08.2003
Цитата:
Originally posted by sasha_san
Hi there,
мое первое сообщение не сохранилось на форуме - интересно почему? Или его кто-то удалил?
Посему, по второму разу.
1) надо подсчитать обычную сумму во всех полях DBGrida, однако этот вот код почему-то не работает

long int a;
[COLOR=blue]
Table2->First();
while(!Table2->Eof)
{
a = Table1->FieldByName("Paid")->AsInteger;
a = a + a;
Table2->Next();
}
Table2->First();
StaticTotal->Caption = IntToStr(a);
[/COLOR]



Как я понимаю, код, вообще-то, должен быть примерно таким:

Код:
__int64        a    = 0;
// long int имеет ту же размерность, что и int,
// а значит, может произойти переполнение.
// Следовательно, используем __int64
TIntegerField *Paid = dynamic_cast<TIntegerField *>(Table1->FieldByName("Paid"));
// Проверку на *Paid == NULL опускаем,
// будем считать, что "Paid" заведомо всегда целочисленное.
Table2->First();
while(!Table2->Eof)
{
    a += Paid->AsInteger;
    Table2->Next();
}
Table2->First();
StaticTotal->Caption = IntToStr(a);
10
14 марта 2006 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by sasha_san
Спасибо, а как несчет первого? :P


Или первая задача сформулирована некорректно, или одно из двух.

Цитата:

1) надо подсчитать обычную сумму во всех полях DBGrida, однако этот вот код почему-то не работает


Стоит задача суммирования по полям, а приведенный код выполняет суммирование по записям, да еще неправильно (строка "a = a + a" все портит).

Цитата:
И кстати, по поводу второго - я имел в виду не операторы, из которых составляются функции, а функции, из которых составляются функции, причем в многоярусном варианте...


Функции и есть разновидность операторов. Это операторы, описанные программистом, т. е. тобой. Структурная теорема верна и для них.

Грамотно написанная программа состоит из большого числа функций по десять-двадцать строк. Неспроста же объектно-ориентированное программирование появилось.

9.1K
14 марта 2006 года
sasha_san
24 / / 01.02.2006
Цитата:
Originally posted by Freeman
Или первая задача сформулирована некорректно, или одно из двух.


Стоит задача суммирования по полям, а приведенный код выполняет суммирование по записям, да еще неправильно (строка "a = a + a" все портит).


Функции и есть разновидность операторов. Это операторы, описанные программистом, т. е. тобой. Структурная теорема верна и для них.

Грамотно написанная программа состоит из большого числа функций по десять-двадцать строк. Неспроста же объектно-ориентированное программирование появилось.




Да-да, я не вполне точно выразился, имелось в виду сумма по записям - вертикально (сумму по полям можно сделать обычным CalcFields)

9.1K
14 марта 2006 года
sasha_san
24 / / 01.02.2006
Цитата:
Originally posted by Plisteron
Как я понимаю, код, вообще-то, должен быть примерно таким:
Код:
__int64        a    = 0;
// long int имеет ту же размерность, что и int,
// а значит, может произойти переполнение.
// Следовательно, используем __int64
TIntegerField *Paid = dynamic_cast<TIntegerField *>(Table1->FieldByName("Paid"));
// Проверку на *Paid == NULL опускаем,
// будем считать, что "Paid" заведомо всегда целочисленное.
Table2->First();
while(!Table2->Eof)
{
    a += Paid->AsInteger;
    Table2->Next();
}
Table2->First();
StaticTotal->Caption = IntToStr(a);



Спасибо, но честно говоря, этот код не работает. И потом. Можно объяснить причину динамического, если я правильно понял, создания поля Paid, которое уже есть?
То, что значение поля Paid всегда больше нуля, подразумевается.

395
14 марта 2006 года
RelB
367 / / 09.11.2002
Цитата:
Originally posted by sasha_san
Спасибо, но честно говоря, этот код не работает. И потом. Можно объяснить причину динамического, если я правильно понял, создания поля Paid, которое уже есть?
То, что значение поля Paid всегда больше нуля, подразумевается.


Честно говоря я давно на Билдере уже не писал ничего... Далее по существу...
Это не динамическое создание, а cast, т.е. динамическое приведение указателя одного типа к другому...

Далее, суммирование я бы точно бы так не делал, лучше всего использовать TQuery и что-то типа "SELECT SUM(Paid) FROM ...... "

294
14 марта 2006 года
Plisteron
982 / / 29.08.2003
Цитата:
Originally posted by sasha_san
Спасибо, но честно говоря, этот код не работает. И потом. Можно объяснить причину динамического, если я правильно понял, создания поля Paid, которое уже есть?
То, что значение поля Paid всегда больше нуля, подразумевается.


1. Код я, конечно, не тестировал. И всё-таки, что значит: "Не работает"? Есть сообщения об ошибках на этапе компиляции или линковании, вылетает по run-time exception или всё работает, но выводит неверный ответ?
2. Сейчас я не поленился и протестировал. Не считая опечатки Table1->FieldByName("Paid") ---> заменить на Table2->FieldByName("Paid") всё нормально, ответ даёт правильный.
3. Объясняю. В твоём случае в цикле происходит примерно следующее: у Table2 вызывается метод FieldByName, который ищет по списку полей нужное нам и приводит его к типу TFIeld* (а было TIntegerField*); FieldByName возврацает TField*, у которого вызывается метод AsInteger, который приводит TField* к TIntegerField и возвращает целое значение. И так каждую итерацию. Я один раз перед началом цикла формирую ссылочку на нужное мне поле с нужным мне типом и экономлю кучу тактов процессора, которые можно использовать в другом месте. :) Почему я акцетировал внимание на отсутствующей проверке указателя Paid на NULL. Если у нас неизвестная нам таблица (в которой всё-же есть поле Paid), и данное поле там имеет тип не Integer, а, скажем, String, то, понятно, к типу TIntegerField* оно не приведётся, и конструкция dynamic_cast<TIntegerField *>(Table2->FieldByName("Paid")) возвратит NULL. Соответственно, ничего работать не будет.
Кстати, поскольку у нас объект Paid уже TIntegerField*, можно использовать на Paid->AsInteger, а Paid->Value.

294
14 марта 2006 года
Plisteron
982 / / 29.08.2003
Цитата:
Originally posted by RelB
Честно говоря я давно на Билдере уже не писал ничего... Далее по существу...
Это не динамическое создание, а cast, т.е. динамическое приведение указателя одного типа к другому...

Далее, суммирование я бы точно бы так не делал, лучше всего использовать TQuery и что-то типа "SELECT SUM(Paid) FROM ...... "



Если мне надо просуммировать, я действительно выполняю запрос "SELECT SUM(Paid) FROM ...... ".
Но, во-первых, возможно, использовать человеку TQuery может не позволять религия ;); во-вторых, может быть, нужна более сложная обработка значений поля, которую не может предоставить BDE с его убогой версией SQL, автор немножко упростил задачу, приведя не этот сложный алгоритм обработки, а всего лишь суммирование.

9.1K
14 марта 2006 года
sasha_san
24 / / 01.02.2006
Цитата:
Originally posted by Plisteron
Если мне надо просуммировать, я действительно выполняю запрос "SELECT SUM(Paid) FROM ...... ".
Но, во-первых, возможно, использовать человеку TQuery может не позволять религия ;); во-вторых, может быть, нужна более сложная обработка значений поля, которую не может предоставить BDE с его убогой версией SQL, автор немножко упростил задачу, приведя не этот сложный алгоритм обработки, а всего лишь суммирование.



И все-таки оно не работает. Может быть дело в том, что у меня обычная локальная БД? Не помню, говорил я это или нет.
А сообщение выдается такое - Project1 raised exception class EAccessViolation with message 'Access violation at address 00402177 in module Project1.exe' Read of address 00000000. Process stoped.
:{ :{

294
14 марта 2006 года
Plisteron
982 / / 29.08.2003
Цитата:
Originally posted by sasha_san
И все-таки оно не работает. Может быть дело в том, что у меня обычная локальная БД? Не помню, говорил я это или нет.
А сообщение выдается такое - Project1 raised exception class EAccessViolation with message 'Access violation at address 00402177 in module Project1.exe' Read of address 00000000. Process stoped.
:{ :{


Убедись, что поле Paid в табличке действительно целочисленое, скопируй код и нужные ресурсы в новый проект и убедись, что ошибка не в моём коде, а где-то в твоём. :D Или пройдись отладчиком, найди, где возникает ошибка.
Ошибка Access Voшation записи/чтения по адресу 0 означает, что ты пытаешься работать с указателем, который NULL.

9.1K
14 марта 2006 года
sasha_san
24 / / 01.02.2006
Цитата:
Originally posted by Plisteron
Убедись, что поле Paid в табличке действительно целочисленое, скопируй код и нужные ресурсы в новый проект и убедись, что ошибка не в моём коде, а где-то в твоём. :D Или пройдись отладчиком, найди, где возникает ошибка.
Ошибка Access Voшation записи/чтения по адресу 0 означает, что ты пытаешься работать с указателем, который NULL.



Dear Plisteron, спасибо, наконец-то все заработало.
Однако, конечный код выглядит так
[COLOR=blue]
void __fastcall TForm1::CalcSum()
{
__int64 a;
a = 0;

Table2->First();
while(!Table2->Eof)
{
a += Table2->FieldByName("Paid")->AsInteger;
Table2->Next();
}
Table2->First();
StaticTotal->Caption = IntToStr(a);
}
//-----------------------------------------------
[/COLOR]


:D :D :D :D :D :D

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог