Форум программистов, компьютерный форум, киберфорум
C++ Builder: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/13: Рейтинг темы: голосов - 13, средняя оценка - 5.00
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66

Выполнение операций над датами в DBGrid

21.06.2015, 19:16. Показов 2580. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Создаю программу в C++ Builder XE7. Нужно посчитать продолжительность рабочего дня (вычесть ВРЕМЯ_ОКОНЧАНИЕ из ВРЕМЯ_НАЧАЛО). В Access это поле имеет вычисляемый тип данных. Думал решить эту проблему следующим образом:
C++
1
dynamic_cast<TDateTimeField*>(Handbook->DBGrid->DataSource->DataSet->Fields->FindField("ПРОДОЛЖИТЕЛЬНОСТЬ"))->DisplayFormat = "hh:nn";
но понял, что это глупость Помогите пожалуйста решить эту задачку
Миниатюры
Выполнение операций над датами в DBGrid   Выполнение операций над датами в DBGrid  
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.06.2015, 19:16
Ответы с готовыми решениями:

Выполнение операций над множествами
Задано некоторое множество М и некоторое множество Т того же типа. Подсчитать, сколько элементов из множеств М и Т совпадают.

Выполнение арифметических операций над числами
В C # введите программу, которая запрашивает и читает два числа с клавиатуры. После этого программа должна выполнить основные...

Выполнение базовых арифметических операций над числами
Описать функцию Calc (A,B,Op) вещественного типа выполняющую над нулевыми числами А и В одну из арифметических операций и возвращающую ее...

34
 Аватар для Sasha
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
21.06.2015, 21:03
вот пример
C++
1
2
3
4
5
void __fastcall TForm2::Button1Click(TObject *Sender)
{
TTime StartTime = StrToTime("8:15"),EndTime = StrToTime("17:00");
ShowMessage((EndTime-StartTime).TimeString());
}
0
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
21.06.2015, 21:47  [ТС]
Sasha, Попробовал так:
C++
1
2
3
4
TTime
    StartTime = ADOQuery1->Fields->Fields[5]->AsDateTime,
    EndTime = ADOQuery1->Fields->Fields[6]->AsDateTime;
ADOQuery1->Fields->Fields[7]->AsString = (EndTime-StartTime).TimeString();
Вышла ошибка

Попробовал по-другому:
C++
1
2
3
4
TTime
    StartTime = ADOQuery1->Fields->Fields[5]->AsDateTime,
    EndTime = ADOQuery1->Fields->Fields[6]->AsDateTime;
ADOQuery1->Fields->Fields[7]->AsDateTime = EndTime-StartTime;
Вышла другая ошибка

Я так понимаю, это из-за того что в БД у этого поля вычисляемый тип данных? Помогите пожалуйста это исправить
0
 Аватар для Sasha
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
21.06.2015, 22:07
А так?
C++
1
ADOQuery1->Fields->Fields[7]->AsDateTime = ADOQuery1->Fields->Fields[6]->AsDateTime - ADOQuery1->Fields->Fields[5]->AsDateTime;
0
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
21.06.2015, 22:08  [ТС]
Sasha, Ошибка(
0
 Аватар для Sasha
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
21.06.2015, 22:10
Или ещё вот так вот попробуй
C++
1
ADOQuery1->Fields->Fields[7]->AsTime = ADOQuery1->Fields->Fields[6]->AsTime - ADOQuery1->Fields->Fields[5]->AsTime;
0
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
21.06.2015, 22:19  [ТС]
Sasha, Ошибка при компиляции

[bcc32 Error] TimeTracking_2.cpp(98): E2316 'AsTime' is not a member of 'TField'

Добавлено через 6 минут
Вот почему программа не может нормально взять готовые данные из БД
0
 Аватар для Sasha
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
21.06.2015, 23:07
Лучший ответ Сообщение было отмечено Bor1and как решение

Решение

Попробуй поля задать явно
C++
1
2
3
4
void __fastcall TForm2::ADOQuery1CalcFields(TDataSet *DataSet)
{
 ADOQuery1->FieldByName("Differ")->AsDateTime  = ADOQuery1->FieldByName("End")->AsDateTime - ADOQuery1->FieldByName("Start")->AsDateTime;
}
Добавлено через 1 минуту
А полю Продолжительность задай назначение калькулятивности
1
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
21.06.2015, 23:11  [ТС]
Sasha, А как это задать?
0
 Аватар для Sasha
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
21.06.2015, 23:29
Цитата Сообщение от Bor1and Посмотреть сообщение
Sasha, А как это задать?
Вот так
C++
1
2
3
4
5
6
__fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
{
  dynamic_cast<TDateTimeField*>(DBGrid1->DataSource->DataSet->Fields->FindField("ПРОДОЛЖИТЕЛЬНОСТЬ"))->FieldKind = fkCalculated;
 
}

C++
1
2
3
4
void __fastcall TForm2::ADOQuery1CalcFields(TDataSet *DataSet)
{
 ADOQuery1->FieldByName("ПРОДОЛЖИТЕЛЬНОСТЬ")->AsDateTime  = ADOQuery1->FieldByName("ВРЕМЯ_ОКОНЧАНИЕ")->AsDateTime - ADOQuery1->FieldByName("ВРЕМЯ_НАЧАЛО")->AsDateTime;
}
1
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
21.06.2015, 23:39  [ТС]
Sasha, Куда не вставлю, везде ошибка. Пробовал ставить и до Active, и после
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
AnsiString buffer;
ADOTable1->RecNo = CBSubDiv->ItemIndex + 1;
buffer = Handbook->ADOTable1->Fields->Fields[0]->AsString;
DataSource1->DataSet = Handbook->ADOQuery1;
ADOQuery1->SQL->Text = "SELECT СОТРУДНИКИ.ФИО, ДАННЫЕ.ДАТА, ДАННЫЕ.МЕСТО, "
                    "ДАННЫЕ.ЦЕЛЬ, ДАННЫЕ.СП_ПЕРЕДВИЖ, ДАННЫЕ.ВРЕМЯ_НАЧАЛО, "
                    "ДАННЫЕ.ВРЕМЯ_ОКОНЧАНИЕ, ДАННЫЕ.ПРОДОЛЖИТЕЛЬНОСТЬ "
                    "FROM (ДАННЫЕ INNER JOIN ПОДРАЗДЕЛЕНИЕ ON "
                    "ДАННЫЕ.Код_подр = ПОДРАЗДЕЛЕНИЕ.КОД_ПОДР) "
                    "INNER JOIN СОТРУДНИКИ ON (ДАННЫЕ.КОД_СОТР = "
                    "СОТРУДНИКИ.КОД_СОТР) AND (ПОДРАЗДЕЛЕНИЕ.КОД_ПОДР = "
                    "СОТРУДНИКИ.КОД_ПОДР)"
                    "WHERE (((ПОДРАЗДЕЛЕНИЕ.КОД_ПОДР)=" + buffer + "))";
dynamic_cast<TDateTimeField*>(DBGrid->DataSource->DataSet->Fields->FindField("ПРОДОЛЖИТЕЛЬНОСТЬ"))->FieldKind = fkCalculated;
ADOQuery1->Active = true;
Ошибку не выдает, если вставить эту строку кода в
C++
1
2
3
4
5
void __fastcall THandbook::ADOQuery1CalcFields(TDataSet *DataSet)
{
    dynamic_cast<TDateTimeField*>(DBGrid->DataSource->DataSet->Fields->FindField("ПРОДОЛЖИТЕЛЬНОСТЬ"))->FieldKind = fkCalculated;
    ADOQuery1->FieldByName("ПРОДОЛЖИТЕЛЬНОСТЬ")->AsDateTime  =  ADOQuery1->FieldByName("ВРЕМЯ_ОКОНЧАНИЕ")->AsDateTime - ADOQuery1->FieldByName("ВРЕМЯ_НАЧАЛО")->AsDateTime;
}
Но так данные остаются некорректными.
Миниатюры
Выполнение операций над датами в DBGrid  
0
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
22.06.2015, 22:29  [ТС]
Sasha, Так, я тут подумал и решил решить эту задачку следующим образом:
Изначально не выводить поле ПРОДОЛЖИТЕЛЬНОСТЬ, а добавить это поле в DBGrid, так как это поле в самой БД все равно будет меняться корректно:
C++
1
2
3
4
5
6
7
8
9
TColumn *Column;
for(int i = 0; i < DataSource1->DataSet->FieldCount + 1; i++)
{
    Column = DBGrid->Columns->Add();
    if (i < DataSource1->DataSet->FieldCount)
        Column->Field = DataSource1->DataSet->Fields->Fields[i];
    if (i >= DataSource1->DataSet->FieldCount)
        Column->Title->Caption = "ПРОДОЛЖИТЕЛЬНОСТЬ";
}
Добавить у меня получилось, но возник вопрос, как же внести туда данные, если использовать этот код, то выходит ошибка:
C++
1
DBGrid->Fields[7]->AsString = "asdasd" ;
Или же мои опасения оправданы и внести туда данные попросту невозможно?
0
 Аватар для Sasha
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
23.06.2015, 00:40
Bor1and, а так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <vcl.h>
#pragma hdrstop
 
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::ADOQuery1AfterOpen(TDataSet *DataSet)
{
dynamic_cast<TDateTimeField*>(DBGrid1->DataSource->DataSet->Fields->FindField("ВРЕМЯ_НАЧАЛО"))->DisplayFormat = "hh:mm";
dynamic_cast<TDateTimeField*>(DBGrid1->DataSource->DataSet->Fields->FindField("ВРЕМЯ_КОНЕЦ"))->DisplayFormat = "hh:mm";
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormShow(TObject *Sender)
{
   ADOQuery1->Close();
   ADOQuery1->SQL->Clear();
   ADOQuery1->SQL->Add("Select *from qwe");
   ADOQuery1->Open();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
 ADOQuery1->Close();
 ADOQuery1->SQL->Clear();
 ADOQuery1->SQL->Add("Select ВРЕМЯ_НАЧАЛО, ВРЕМЯ_КОНЕЦ, FORMAT(ВРЕМЯ_КОНЕЦ - ВРЕМЯ_НАЧАЛО,'hh:mm') AS ПРОДОЛЖИТЕЛЬНОСТЬ from qwe");
 ADOQuery1->Open();
int widthcolumn = (DBGrid1->Width)/(DBGrid1->FieldCount);
 TColumn *Column;
  for(int i = 0; i < DataSource1->DataSet->FieldCount; i++)
 {
    Column = DBGrid1->Columns->Add();
    Column->Field = DataSource1->DataSet->Fields->Fields[i];
    Column->Alignment = taCenter;
    Column->Title->Alignment = taCenter;
    DBGrid1->Columns->Items[i]->Width = widthcolumn;
  }
}
//--------------------------------------
0
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
23.06.2015, 12:02  [ТС]
Sasha, вот что в итоге
Миниатюры
Выполнение операций над датами в DBGrid  
0
 Аватар для Sasha
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
23.06.2015, 12:34
Bor1and, а если вообще убрать поле продолжительность из базы?
0
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
23.06.2015, 12:55  [ТС]
Sasha, Хм, тоже самое
0
 Аватар для Sasha
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
23.06.2015, 18:30
Выкладываю тебе проект
Вложения
Тип файла: rar ert.rar (11.9 Кб, 8 просмотров)
0
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
24.06.2015, 21:35  [ТС]
Sasha, Спасибо большое) Все понял, это все из-за поставщика, у меня - Microsoft.ACE.OLEDB.12.0,
у вас - Microsoft.Jet.OLEDB.4.0. Но к сожалению, ваш поставщик не воспринимает формат *.accdb. А его я и изменить не могу.

Добавлено через 32 минуты
А по другому значит никак?

Добавлено через 23 часа 45 минут
Sasha, сейчас попытался сделать так
C++
1
ADOQuery1->FieldByName("ПРОДОЛЖИТЕЛЬНОСТЬ")->AsDateTime = ADOQuery1->FieldByName("ВРЕМЯ_ОКОНЧАНИЕ")->AsDateTime - ADOQuery1->FieldByName("ВРЕМЯ_НАЧАЛО")->AsDateTime;
но выходит ошибка, говорящая о том, что "Набор данных не находится в режиме редактирования или в режиме вставки". Тогда я сделал так:
C++
1
2
ADOQuery1->Edit();
    ADOQuery1->FieldByName("ПРОДОЛЖИТЕЛЬНОСТЬ")->AsDateTime = ADOQuery1->FieldByName("ВРЕМЯ_ОКОНЧАНИЕ")->AsDateTime - ADOQuery1->FieldByName("ВРЕМЯ_НАЧАЛО")->AsDateTime;
так работает хорошо, но если кликнуть в какое-нибудь поле, то значение в ПРОДОЛЖИТЕЛЬНОСТЬ становится пустым.

P.S. Пробовал и так
C++
1
2
3
ADOQuery1->Edit();
    ADOQuery1->FieldByName("ПРОДОЛЖИТЕЛЬНОСТЬ")->AsDateTime = ADOQuery1->FieldByName("ВРЕМЯ_ОКОНЧАНИЕ")->AsDateTime - ADOQuery1->FieldByName("ВРЕМЯ_НАЧАЛО")->AsDateTime;
    ADOQuery1->Post();
но это погоду не сделало. Просто поле сразу же становится пустым.
0
 Аватар для Sasha
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
24.06.2015, 23:54
Bor1and, а попробуй ка вот так вот
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 void __fastcall TForm2::ADOQuery1AfterOpen(TDataSet *DataSet)
{
dynamic_cast<TDateTimeField*>(DBGrid1->DataSource->DataSet->Fields->FindField("ВРЕМЯ_НАЧАЛО"))->DisplayFormat = "hh:mm";
dynamic_cast<TDateTimeField*>(DBGrid1->DataSource->DataSet->Fields->FindField("ВРЕМЯ_КОНЕЦ"))->DisplayFormat = "hh:mm";
dynamic_cast<TDateTimeField*>(DBGrid1->DataSource->DataSet->Fields->FindField("ПРОДОЛЖИТЕЛЬНОСТЬ"))->DisplayFormat = "hh:mm";
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormShow(TObject *Sender)
{
   ADOQuery1->Close();
   ADOQuery1->SQL->Clear();
   ADOQuery1->SQL->Add("Select *from qwe");
   ADOQuery1->Open();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
 ADOQuery1->Close();
 ADOQuery1->SQL->Clear();
 ADOQuery1->SQL->Add("UPDATE qwe set ПРОДОЛЖИТЕЛЬНОСТЬ  = ВРЕМЯ_КОНЕЦ - ВРЕМЯ_НАЧАЛО");
 ADOQuery1->ExecSQL();
 ADOQuery1->Close();
 ADOQuery1->SQL->Clear();
 ADOQuery1->SQL->Add("Select *from qwe");
 ADOQuery1->Open();
 
}
//---------------------------------------------------------------------------
Этот код вычисляет время и сохраняет в базу и выводит сразу изменения

Добавлено через 1 минуту
Только поменяй имя таблицы
0
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
25.06.2015, 00:41  [ТС]
Sasha, блин, невозможно обновить поле ПРОДОЛЖИТЕЛЬНОСТЬ; не обновляемое поле
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.06.2015, 00:41
Помогаю со студенческими работами здесь

Чтение чисел из фаила и выполнение операций над ними
Товарищи выручайте пожалуйста! Необходимо на Си, написать программу для считывания из файла 3 чисел, затем чтобы выполняла арифметические...

Выполнение операций сложения, вычитания и умножения над матрицами целых чисел
Нужно разработать прогу, которая обеспечивает выполнение операций сложения, вычитания и умножения над матрицами целых чисел. Выбор...

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

Класс MyMath обеспечивающий выполнение операций сравнения над двумя вещественными числами
Класс должен включать в себя поля x и y (числа, над которыми выполняются операции), а также следующие методы: • bool isequal() –...

Выполнение арифметических операций над числами, приминение стандартых функций к типам целых и действительных
Помогите заделать в лазарусе


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru