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

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

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

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

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

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

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

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

34
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
21.06.2015, 21:03 2
вот пример
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  [ТС] 3
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();
Вышла ошибка
Выполнение операций над датами в DBGrid

Попробовал по-другому:
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;
Вышла другая ошибка
Выполнение операций над датами в DBGrid

Я так понимаю, это из-за того что в БД у этого поля вычисляемый тип данных? Помогите пожалуйста это исправить
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
21.06.2015, 22:07 4
А так?
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  [ТС] 5
Sasha, Ошибка(
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
21.06.2015, 22:10 6
Или ещё вот так вот попробуй
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  [ТС] 7
Sasha, Ошибка при компиляции

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

Добавлено через 6 минут
Вот почему программа не может нормально взять готовые данные из БД
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
21.06.2015, 23:07 8
Лучший ответ Сообщение было отмечено 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  [ТС] 9
Sasha, А как это задать?
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
21.06.2015, 23:29 10
Цитата Сообщение от 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  [ТС] 11
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  [ТС] 12
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
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
23.06.2015, 00:40 13
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  [ТС] 14
Sasha, вот что в итоге
Миниатюры
Выполнение операций над датами в DBGrid  
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
23.06.2015, 12:34 15
Bor1and, а если вообще убрать поле продолжительность из базы?
0
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
23.06.2015, 12:55  [ТС] 16
Sasha, Хм, тоже самое
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
23.06.2015, 18:30 17
Выкладываю тебе проект
Вложения
Тип файла: rar ert.rar (11.9 Кб, 8 просмотров)
0
1 / 1 / 0
Регистрация: 03.02.2014
Сообщений: 66
24.06.2015, 21:35  [ТС] 18
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
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
24.06.2015, 23:54 19
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  [ТС] 20
Sasha, блин, невозможно обновить поле ПРОДОЛЖИТЕЛЬНОСТЬ; не обновляемое поле
0
25.06.2015, 00:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.06.2015, 00:41
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru