Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Ошибка при вызове StrToDate в Delphi XE2


Автор: BEST13 30.1.2012, 14:42
Проблема в том, что вызов strTodate выдает ошибку:
Цитата

First chance exception at $00423C3C. Exception class $C0000005 with message 'access violation at 0x00423c3c: read of address 0x00000000'. Process P_sklad.exe (7124)  


В начале думал, может формат даты не правильный пробовал разные варианты: 10.10.2010 10/10/2010  10.10.10 10/10/10. В любом случае ошибка.
Пробовал на всякий случай переименую инициализировать, не помогает. 
Вот код :
Код

procedure TF_add_rec.B_addClick(Sender: TObject);
var Nazv:string; tt, proizv, kol, izmer:integer;
    datesend,daterecieved:Tdatetime; cena, stoimost:real;
begin
 datesend:=date;
  Nazv:=E_add_nazv.Text;
  tt:=DBLCB_add_Type.KeyValue;
  proizv:=DBLCB_add_proizvod.KeyValue;
  cena:=strtofloat(E_add_cena.text);
  kol:=strtoint(E_add_kol.Text);
  izmer:=DBLCB_add_Izmer.KeyValue;
  stoimost:=strtofloat(E_add_stoim.text);
  datesend:=strtodate(E_add_datesend.Text);
  daterecieved:=strtodate(E_add_daterecievad.text);
  With DM.AQ_postavki do
  begin
    Close;
    SQL.Clear;
    SQL.Add('INSERT INTO Postavki ( NazvTovara, TovarType, Proizvoditel, Cena, Kol, Izmer, Stoimost, DateSend, DateReceived ) VALUES ( NazvTovara, :TovarType, Proizvoditel, :Cena, :Kol, :Izmer, :Stoimost, :DateSend, :DateReceived);');
    parameters.parambyname('NazvTovara').Value:= Nazv;
    parameters.parambyname('TovarType').Value:= tt;
    parameters.parambyname('Proizvoditel').Value:= proizv;
    parameters.parambyname('Cena').Value:= cena;
    parameters.parambyname('Kol').Value:= Kol;
    parameters.parambyname('Izmer').Value:= izmer;
    parameters.parambyname('Stoimost').Value:= stoimost;
    parameters.parambyname('DateSend').Value:= datesend;
    parameters.parambyname('DateReceived').Value:= daterecieved;
    ExecSQL;
    SQL.Add('SELECT Kod AS [ID], NazvTovara AS [Название],  TovarType AS [Тип],'+
 ' Proizvoditel AS [Производитель], Cena AS [Цена], Kol AS [Количество],'+
 ' Izmer AS [Измеряеться], Stoimost AS [Стоемость],'+
 ' DateSend AS [Дата отправки], DateReceived  AS [Дата получения]'+
 ' FROM Postavki; ');
    Open;
  end;
  F_main.DBG_postavki.Columns[0].Width:=30;
  F_main.DBG_postavki.Columns[1].Width:=150;
  F_main.DBG_postavki.Columns[2].Width:=100;
  F_main.DBG_postavki.Columns[3].Width:=60;
  F_main.DBG_postavki.Columns[4].Width:=50;
  F_main.DBG_postavki.Columns[5].Width:=50;
  F_main.DBG_postavki.Columns[6].Width:=40;
  F_main.DBG_postavki.Columns[7].Width:=40;
  F_main.DBG_postavki.Columns[8].Width:=50;
  F_main.DBG_postavki.Columns[9].Width:=50;
end;

   

Автор: superVad 30.1.2012, 15:27
В какой строчке ошибка?
Что то мне кажется, что это вина не strtodate.

После 29 строчки надо бы очистить текст запроса. Но это вообще не правильно как то - юзать один компонент для вставки и просмотра таким образом...

Автор: k0rvin 30.1.2012, 15:30
попробуй объявить dateSent, dateReceived : TDate, а не TDateTime

Добавлено через 6 минут и 20 секунд
Вообще, судя по квадратным скобкам в тексте запроса, я бы предположил, что ТС имеет дело с МС Аксессом. Если так, то у коллеги похожая проблема была, и дело не в StrToDate, а в том, что ADOQuery почему-то неправильно передает дату как параметр, если ее встроить в запрос конкатенацией, то запрос сработает нормально =/

Автор: BEST13 30.1.2012, 15:51
superVad, Ошибка после 13 строки.  Насчет очистки, спасибо, пропустил вы правы; А не заметил потому, что до запроса не доходит.

k0rvin, Я пробовал делать конвертацию вообще на другой форме только пи запуске, проги , с введенной заранее датой, в итоге все равно ошибка. 
 Да, и переменная типа Tdate не спасла меня...

Автор: k0rvin 30.1.2012, 16:06
А попробуй формат "2010-10-10" (YYYY-MM-DD)

Автор: BEST13 30.1.2012, 16:32
k0rvin,  В итоге все равно ошибка. 
Я тут подумал, у меня какой то глюк в Аксесе не отображается дата в коротком формате(пробывал два офиса х64-х86), может дело  в самой виндоус и может в нней какой-то глюк?

Автор: БелАмор 30.1.2012, 18:18
Пропущены двоеточия для двух параметров:

Цитата(BEST13 @  30.1.2012,  14:42 Найти цитируемый пост)
    SQL.Add('INSERT INTO Postavki ( NazvTovara, TovarType, Proizvoditel, Cena, Kol, Izmer, Stoimost, DateSend, DateReceived ) VALUES ( NazvTovara, :TovarType, Proizvoditel, :Cena, :Kol, :Izmer, :Stoimost, :DateSend, :DateReceived);');


Автор: superVad 30.1.2012, 18:21
Попробуй компонент может другой, конкретно для даты (TDateEdit). Тогда не надо будет конвертировать.

Автор: CodeMonkey 31.1.2012, 02:31
Цитата
Я пробовал делать конвертацию вообще на другой форме только пи запуске, проги , с введенной заранее датой, в итоге все равно ошибка


Барабашки, не иначе.

Что, и в пустом проекте тоже так же? 

Автор: Akella 31.1.2012, 10:50
Первый раз вижу, чтобы при конвертации была ошибка access violation.
Ищи в другом месте. Обрати внимание, что access violation read of address 0x00000000 намекает тебе на то, что ты обращаешься к ещё не созданному объекту.




Цитата(superVad @  30.1.2012,  15:27 Найти цитируемый пост)
В какой строчке ошибка?


Цитата(BEST13 @  30.1.2012,  15:51 Найти цитируемый пост)
superVad, Ошибка после 13 строки.


Мне напоминает анекдот про грузинскую школу:
- Кацо, сколка будэт 5ю5?
- Двацасэм!
- На да, гдэ-то так, двацапять-двацасэм...


Ой, неужели так трудно отладчиком выяснить строку ошибки?

Автор: BEST13 31.1.2012, 23:12
БелАмор,  да спасибо, я уже и сам заметил и исправил.  

superVad,  не вариант, есть условие использовать только стандартные компоненты.

Цитата(CodeMonkey @  31.1.2012,  02:31 Найти цитируемый пост)

Барабашки, не иначе.

Что, и в пустом проекте тоже так же?  


Да в пустом, тоже самое(

Притом, что это функция, отлично работает в 7 делфи установленной параллельно(  
Цитата(Akella @  31.1.2012,  10:50 Найти цитируемый пост)
Первый раз вижу, чтобы при конвертации была ошибка access violation.
Ищи в другом месте. Обрати внимание, что access violation read of address 0x00000000 намекает тебе на то, что ты обращаешься к ещё не созданному объекту.
,
 Я пробовал создать пустой проект, и там просто с конвертировать и вылазит, эта ошибка.

Цитата(Akella @  31.1.2012,  10:50 Найти цитируемый пост)

Ой, неужели так трудно отладчиком выяснить строку ошибки? 


Ну, так я в отладчике и смотрел, вылетает ошибка на 13 строке, то есть когда нание перехожу, тогда и вылетает.
-------------------
Я по пробывал запустить, этот проект на другом компе с 32х битной семеркой но с той же делфи, установлена с одного же диска, и все работает отлично...

Я не знаю связано ли это , как-то, также здесь ( на томже компе ) в Аксесе не хочет отображаться дата в коротком формате в полях .
Ставил и 32х и 64х битный аксесс. Может проблема в винде и у неё, что  с параметрами даты?

  

Автор: northener 1.2.2012, 00:48
Блин!
Ну сколько раз нужно объяснять, что наличие AV - есть точное подтверждение, что в программе есть код неверно работающий с памятью, но отсутствие AV ровным счётом ничего не значит!

Цитата(BEST13 @  31.1.2012,  23:12 Найти цитируемый пост)
Да в пустом, тоже самое(

Вранье. 
И как всегда виновата винда!

Автор: CodeMonkey 1.2.2012, 01:51
Цитата
Я не знаю связано ли это , как-то, также здесь ( на томже компе ) в Аксесе не хочет отображаться дата в коротком формате в полях .
Ставил и 32х и 64х битный аксесс. Может проблема в винде и у неё, что  с параметрами даты?


И причём тут Access, если у тебя в пустом проекте та же проблема?

Как задают вопросы на форумах:

Идет мент. Смотрит - фонарь стоит, под фонарем лужа, в луже мужик сидит.
- Чё здесь делаешь?
- Да вот, часы потерял. теперь ищу.
Ну, мент думает - дай помогу. Искал-искал, весь перемазался - нету часов.
- Слушай, мужик. Нету тут никаких часов!
- Да я знаю. Я их вон там, возле забора потерял.
- А ЧЕ ТЫ ИХ ЗДЕСЬ ИЩЕШЬ???
- А тут светлее.


Логика железная.

Добавлено @ 01:54
Кидай свой проект с барабашками сюда, будем резать.

P.S. Пустой проект кидай, если не понял.

Автор: superVad 1.2.2012, 11:18
BEST13, есть TDateTimePicker - вроде стандартный.

А так то, конечно:
Цитата(CodeMonkey @  1.2.2012,  00:51 Найти цитируемый пост)
Кидай свой проект с барабашками сюда, будем резать.P.S. Пустой проект кидай, если не понял.


Автор: BEST13 5.2.2012, 13:15
Всем огромное спасибо, за помощь и участие, плюсики будут)
Разобрался в чем, дела  в настройках винды, слетел формат короткой даты.... там ничего не боло выбрано, не знаю каким образом, такое случилось. Когда выбрал, все заработало и аксес и делфи.   

Автор: Gwire 9.2.2012, 16:41
Цитата(BEST13 @  5.2.2012,  13:15 Найти цитируемый пост)
 в настройках винды, слетел формат короткой даты.... там ничего не боло выбрано, не знаю каким образом, такое случилось.
А где уверенность, что у пользователя твоей программы не слетит формат короткой даты на компе?
Это, тебе небольшой крэшь-тест. Не выдержала.
Используй StrToDateTime(const S: string; const FormatSettings: TFormatSettings). А переменную типа TFormatSettings сохрани в том же TDataModule (пологою DM is TDataModule)

И еще:
Цитата(k0rvin @  30.1.2012,  15:30 Найти цитируемый пост)
 если ее встроить в запрос конкатенацией

Согласен с k0rvin. Используй лучше обычное суммирование строк.
Или юзай лучше проверенный Format(). И он кстати принимает параметр TFormatSettings.

Автор: k0rvin 10.2.2012, 09:36
Цитата(Gwire @ 9.2.2012,  16:41)
Согласен с k0rvin. Используй лучше обычное суммирование строк.

Нет, это не лучше.

Автор: Gwire 10.2.2012, 12:03
Цитата(k0rvin @  10.2.2012,  09:36 Найти цитируемый пост)
Цитата(Gwire @ 9.2.2012,  16:41)
Согласен с k0rvin. Используй лучше обычное суммирование строк.

Нет, это не лучше. 
От чего же?

По вашему 
   ReallocMem();
   Copy();
будет работать хуже чем
  for-to-do
    if-then
    begin
      ReallocMem();
      Copy();
    end;
?
Сканирование с подстановкой никогда не будет работать стабильнее дополнения.

Цитата(k0rvin @  30.1.2012,  15:30 Найти цитируемый пост)
попробуй объявить dateSent, dateReceived : TDate, а не TDateTime
Эти два типа эквивалентны. 
Они оба Double (TTime тоже) и имеют одинаковую структуру. Дни - целые, часы:минуты:секунды.милсек - дробные
Их ввели для удобства написания кода. 

Автор: superVad 10.2.2012, 21:07
Можно в начале работы программы устанавливать ShortDateFormat.

Автор: northener 11.2.2012, 03:28
Цитата(superVad @  10.2.2012,  21:07 Найти цитируемый пост)
Можно в начале работы программы устанавливать ShortDateFormat. 

Можно. Но нужно при этом помнить и о TApplication.UpdateFormatSettings!

Автор: k0rvin 13.2.2012, 08:43
Цитата(Gwire @ 10.2.2012,  12:03)
От чего же?

от того что http://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_SQL-%D0%BA%D0%BE%D0%B4%D0%B0 и не надежно (форматы представления, например, дат могут отличаться в разных СУБД/ОС). И да, параметризованные запросы можно кешировать и исполнять пакетно с разными параметрами.

Автор: Gwire 13.2.2012, 13:32
Цитата(k0rvin @  13.2.2012,  08:43 Найти цитируемый пост)
форматы представления, например, дат могут отличаться в разных СУБД/ОС

Для этого и придуманы TFormatSettings и, например в MS SQL, Set DATEFORMAT (в других тоже СУБД тоже наверняка есть).
Приводишь их к общему виду и никаких проблем не возникает.

Цитата(k0rvin @  13.2.2012,  08:43 Найти цитируемый пост)
от того что не безопасно и не надежно
А по поводу статьи в википедии - интересная статейка, но:
1) Если "злоумышленник" хакнул  ехе-программу получил возможность менять значения параметров, то что ему запретит менять переменную содержащую запрос?
2) Если же вы сами предоставляете возможность пользователю вводить параметры запроса в ручную. Рекомендую изучить термин "Защита от дурака" (http://ru.wikipedia.org/wiki/%D0%97%D0%B0%D1%89%D0%B8%D1%82%D0%B0_%D0%BE%D1%82_%D0%B4%D1%83%D1%80%D0%B0%D0%BA%D0%B0 или http://lurkmore.to/%D0%97%D0%B0%D1%89%D0%B8%D1%82%D0%B0_%D0%BE%D1%82_%D0%B4%D1%83%D1%80%D0%B0%D0%BA%D0%B0)
HTML-я и Javascript это тоже касается.
Ну если, конечно, вы пишете для веб, и передаете параметры открытым каналом или их просто подставить, то такие вещи нужно учитывать.

В PHP переменные не имеют определенного типа. Потому и возникают такие проблемы. 
В Delphi все проще - если я жду Integer (например 5 или 2435159) то туда никак не впихнуть String ('-1 OR 1=1')

А задачу я решил бы как:
Код

const
  CUBDFormat: TFormatSettings = ( // Настроить все параметры как в база их воспринимает.
    DecimalSeparator: '.'; 
    ShortDateFormat: 'YYYY-MM-DD'
  ); 

type
  TPostavkiRec = record
    NazvTovara: String;    
    TovarType: Integer;
    Proizvoditel: Integer;
    Cena: Real;
    Kol: Integer;
    Izmer: Integer;
    Stoimost: Real;
    DateSend: TDataTime; 
    DateReceived: TDataTime;
  end;

function GetInsertQuery(R: TPostavkiRec): String; overload; // можно одно и тоже имя использовать для разных структур
begin
    Result := 'INSERT INTO Postavki (NazvTovara, TovarType, Proizvoditel, Cena, Kol, Izmer, Stoimost, DateSend, DateReceived) VALUES ('+
      ''''+ R.NazvTovara +''','+
      IntToStr(R.TovarType) +','+
      IntToStr(R.Proizvoditel +','+
      FloatToStrF(R.Cena, CUBDFormat) +','+
      IntToStr(R.Kol) +','+
      IntToStr(R.Izmer) +','+
      FloatToStrF(R.Stoimost, CUBDFormat) +','+
      ''''+ DateToStr(R.DateSend, CUBDFormat) +''','+
      ''''+ DateToStr(R.DateReceived, CUBDFormat) +''');';
end;

// . . .

var S: String; R: TPostavkiRec;
begin
    // R.___ := заполняем запись
    S:= GetInsertQuery(R);
    ADOConnectoin.Execute( S );

Автор: k0rvin 13.2.2012, 16:35
Цитата(Gwire @ 13.2.2012,  13:32)
А задачу я решил бы

изобретением собственного велосипеда вместо готового и проверенного решения.

Хоть бы формат даты спрашивал у СУБД, а не в ручную задавал. И что там с кешированием для пакетной обработки запросов?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)