Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ошибка TADODataSet.Locate! проверено в Delphi 6,7,9 
:(
    Опции темы
Петрович
  Дата 17.7.2005, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Блин. Опять проблема с национальными настройками smile.
Есть программа:
Код
program TestLocate;
{$APPTYPE CONSOLE}
uses
  SysUtils,ADODB,ActiveX,ComObj;

const
  DatabaseName    = 'c:\TestDb.mdb';
  CLASS_DBEngine :TGUID ='{00000100-0000-0010-8000-00AA006D2EA4}';

var
  db :TADOConnection;
  ds :TADODataSet;

begin
  WriteLn('initialization');

  try
    CoInitialize(Nil);
    db := TADOConnection.Create(Nil);
    ds := TADODataSet.Create(Nil);

    db.LoginPrompt := False;

    WriteLn('Create database');
    if  FileExists(DatabaseName)  then  DeleteFile(DatabaseName);
    Variant(CreateOleObject(ClassIDToProgID(CLASS_DBEngine)))
      .Workspaces[0]
        .CreateDatabase (DatabaseName, ';LANGID=0x0409;CP=1252;COUNTRY=0', 0);


    db.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0'
                          +';Data Source="'+DatabaseName+'"'
                          ;

    WriteLn('Create Table');
    db.Execute('CREATE TABLE Test (fld decimal(15, 4))');
    db.Execute('INSERT INTO Test VALUES (1.123)');
    db.Execute('INSERT INTO Test VALUES (2.123)');
    db.Execute('INSERT INTO Test VALUES (3.123)');

    WriteLn('Open table');
    ds.Connection := db;
    ds.CommandText := 'SELECT * FROM Test';
    ds.Open;

    WriteLn('Show table');
    while not ds.Eof do begin
      WriteLn(ds.FieldByName('fld').AsString);
      ds.Next;
    end;

    Write('Locate 2.123 ');
    if  ds.Locate('fld',2.123,[])  then
      WriteLn('success')
    else
      WriteLn('fail');

    Write('Locate ''2.123'' ');
    if  ds.Locate('fld','2.123',[])  then
      WriteLn('success')
    else
      WriteLn('fail');

  except on e :Exception do begin
    WriteLn('Error:');
    WriteLn(e.ClassName);
    WriteLn(e.Message);
    end;
  end;

  FreeAndNil(ds);
  FreeAndNil(db);
  CoUninitialize;
  Write('Press <Enter> key for close application ...');  ReadLn;
end.

Так вот. Если в системе установлен разделитель дробной части '.' (точка) то все ок. Оба locate будут успешными. Но, если в системе установлен разделитель дробной части ',' (запятая) то беда. Первый locate не в состоянии найти существующую запись!

Т.е. если в таком случае (разделитель ','), нет возможности найти запись по значению вещественного поля!
Передавать значение в виде строки возможно не всегда.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Grig
Дата 18.7.2005, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 809
Регистрация: 29.4.2005
Где: Иркутск

Репутация: 4
Всего: 16



В файле SysUtils.pas есть переменная DecimalSeparator.
Попробуй использовать ее.
Например:
Код

if DecimalSeparator = '.' then
begin
    if  ds.Locate('fld','2.123',[])  then    //Здесь точка
      WriteLn('success')    
    else    
      WriteLn('fail');
end;
if DecimalSeparator = ',' then
begin
    if  ds.Locate('fld','2,123',[])  then    //А здесь запятая
      WriteLn('success')    
    else    
      WriteLn('fail');
end;

Добавлено @ 11:29
Или во!
Еще круче:
Код

    if  ds.Locate('fld','2'+DecimalSeparator+'123',[])  then 
//......


Это сообщение отредактировал(а) Grig - 18.7.2005, 11:25


--------------------
        
PM MAIL ICQ   Вверх
Alex
Дата 18.7.2005, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 17
Всего: 162



В свое время писал:
Код

function FloatToStr2(Value: Extended): string;
var
  i: Integer;
  s: String;
begin
  s:= FloatToStr(Value);
  i:= Pos(',', s);
  if i = 0 then i:= Pos('.', s);
  if i > 0 then s[i]:= DecimalSeparator;
  Result:= s;
end;



--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Петрович
Дата 18.7.2005, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Ребята, вы меня не поняли.
ds.Locate('fld','2.123',[]) всегда сработает правильно не зависимо от текущего значения DecimalSeparator.
А вот ds.Locate('fld',2.123,[]), опять же вне зависимости от от текущего значения DecimalSeparator, может сработать, а может и не сработать. Все зависит от состояния настройки в системе! Причем, обратите внимание что второй параметр это значение типа Double (Currency, и т.п.).
Специально включил в пост полноценно работающий пример. Можете проверить.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Петрович
Дата 18.7.2005, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Разборки показали что это похоже косяк Microsoft!
У Borland'а, при обработке Locate, происходит преобразование всех числовых параметров в строку, в соответствии с текущими настройками системы (не DecimalSeparator!). Для этого используется функция VarToStr. А полученные значения передаются в COM-объекту Recordset в параметр Criteria метода Find. Так вот при выполнении этого метода, запись и не находится. Более того, когда таких параметров много (поиск по нескольким полям), я иногда наблюдал Exception ADO!
Ему видете-ли похоже всегда надо '.' давать.
Проверял и на MSACCESS, и на MS-SQL.
В MSDN об этом естествеенно ничего не сказано.
В принципе, если бы быть уверенным что Recordset.Find всегда требует '.' в качестве разделителя, то можно было бы подправить ADODB.pas, и выполнять преобразование не зависимо от текущих настроек системы.



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Петрович
Дата 18.7.2005, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Вот. Alex нашел сообщение об аналогичной проблемме http://coding.derkeiler.com/Archive/Delphi...04-03/0290.html


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Akella
Дата 18.7.2005, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



тогда нужно на время работы программы или определённого куска кода (или формы) в системе (глобально) менять разделитель. Вернее Проверять, если не точка, то менять на точку. Пока другого выхода я не вижу.
PM MAIL   Вверх
Петрович
Дата 18.7.2005, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(dsergey @ 18.7.2005, 16:42)
... в системе (глобально) менять разделитель ...

Уж лучше тогда подправить ADODB.pas


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Akella
Дата 18.7.2005, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



продолжай
PM MAIL   Вверх
kobra
Дата 19.7.2005, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



Петрович мне кажется все так и должно быть.
попробуи в начало скрипта вставить
Код

DecimalSeparator := '.';

PM MAIL   Вверх
Alex
Дата 19.7.2005, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 17
Всего: 162



kobra, сам попробуй и увидишь, что это ни как не повлияет.


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
kobra
Дата 19.7.2005, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



извеняюс, не дописал
Код
DecimalSeparator := '.';
ds.Locate('fld',floattostr(2.123),[])  

PM MAIL   Вверх
Петрович
Дата 19.7.2005, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(kobra @ 19.7.2005, 12:42)
извеняюс, не дописал
код Pascal/Delphi
DecimalSeparator := '.';
ds.Locate('fld',floattostr(2.123),[]) 

Блин. Ты сам-то пробовал smile


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
kobra
Дата 19.7.2005, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



Цитата
Блин. Ты сам-то пробовал

да, все работает (по краинеи мере у меня).
PM MAIL   Вверх
Петрович
Дата 19.7.2005, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(dsergey @ 18.7.2005, 17:06)
продолжай

Да вариантов много. Вот например решение "в лоб".
В модуле ADODB.pas, надо подправить процедуру GetFilterStr.
Там есть case:
Код

    case Field.DataType of
      ftDate, ftTime, ftDateTime:
        QuoteCh := '#';
      ftString, ftFixedChar, ftWideString:
        begin
          if Partial and (Value <> '') then
          begin
            Value := Value + '*';
            Operator := ' like ';     { Do not localize }
          end;
          if Pos('''', Value) > 0 then
            QuoteCh := '#' else
            QuoteCh := '''';
        end;
    end;
Так вот, в него надо добавить еще одну веточку:
Код

      ftFloat, ftCurrency, ftBCD, ftFMTBcd:
        begin
          Value := AnsiReplaceStr(VarToStr(Value),GetLocaleChar(GetThreadLocale, LOCALE_SDECIMAL, '.'),'.');
        end;
Ну и в uses раздела implementation добавить StrUtils.

А вообще, все дело в том, что при выполнении преобразования Variant -> String, в некоторых случаях, в частности когда в Variant значение типа Currency, используется процедура преобразования из OS (в данном случае CurrToWStrViaOS).
Мне в принципе не понятно почему в одних случаях используется преобразование реализуемое Delphi, а в других, реализуемое OS. Но, это уже отдельная тема.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Петрович
Дата 19.7.2005, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(kobra @ 19.7.2005, 13:32)
да, все работает (по краинеи мере у меня).

Тогда, если не трудно, укажи версию Delphi на которой ты это пробовал.
И еще, важное напоминание. Не работает только если в системе установлено ','

Это сообщение отредактировал(а) Петрович - 19.7.2005, 13:00


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
kobra
Дата 19.7.2005, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



Код

program TestLocate;
{$APPTYPE CONSOLE}
uses
  SysUtils,ADODB,ActiveX,ComObj;

const
  DatabaseName    = 'c:\TestDb.mdb';
  CLASS_DBEngine :TGUID ='{00000100-0000-0010-8000-00AA006D2EA4}';

var
  db :TADOConnection;
  ds :TADODataSet;

begin
  WriteLn('initialization');

  try
    CoInitialize(Nil);
    db := TADOConnection.Create(Nil);
    ds := TADODataSet.Create(Nil);

    db.LoginPrompt := False;

    WriteLn('Create database');
    if  FileExists(DatabaseName)  then  DeleteFile(DatabaseName);
    Variant(CreateOleObject(ClassIDToProgID(CLASS_DBEngine)))
      .Workspaces[0]
        .CreateDatabase (DatabaseName, ';LANGID=0x0409;CP=1252;COUNTRY=0', 0);


    db.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0'
                          +';Data Source="'+DatabaseName+'"'
                          ;

    WriteLn('Create Table');
    db.Execute('CREATE TABLE Test (fld decimal(15, 4))');
    db.Execute('INSERT INTO Test VALUES (1.123)');
    db.Execute('INSERT INTO Test VALUES (2.123)');
    db.Execute('INSERT INTO Test VALUES (3.123)');

    

    WriteLn('Open table');
    ds.Connection := db;
    ds.CommandText := 'SELECT * FROM Test';
    ds.Open;

    WriteLn('DecimalSeparator -' + DecimalSeparator);
    DecimalSeparator := '.';
    WriteLn('New DecimalSeparator -' + DecimalSeparator);

    WriteLn('Show table');

    while not ds.Eof do begin
      WriteLn(ds.FieldByName('fld').AsString);
      ds.Next;
    end;

    Write('Locate 2.123 ');
    if  ds.Locate('fld',floattostr(2.123),[])  then
      WriteLn('success')
    else
      WriteLn('fail');


    Write('Locate ''2.123'' ');
    if  ds.Locate('fld','2.123',[])  then
      WriteLn('success')
    else
      WriteLn('fail');

  except on e :Exception do begin
    WriteLn('Error:');
    WriteLn(e.ClassName);
    WriteLn(e.Message);
    end;
  end;

  FreeAndNil(ds);
  FreeAndNil(db);
  CoUninitialize;
  Write('Press <Enter> key for close application ...');  ReadLn;
end.
вот полныи код,
скриншот посмотрите, там разделителем установил "/".

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  untitled.JPG 31,03 Kb
PM MAIL   Вверх
kobra
Дата 19.7.2005, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



у меня 7 делфи
а вот скриншот с запетым

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  untitled11.JPG 27,66 Kb
PM MAIL   Вверх
Петрович
Дата 19.7.2005, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Да, но пример-то несколько отличается от приведенного мной. Причем, именно в ключевом моменте:
У меня:
Код

    Write('Locate 2.123 ');
    if  ds.Locate('fld',2.123,[])  then
а у тебя:
Код

    Write('Locate 2.123 ');
    if  ds.Locate('fld',floattostr(2.123),[])  then

При чем тут floattostr?
Дело в том, что в реальной жизни, я не знаю о каком конкретно типе идет речь. У меня сохраняются значения всех полей абстрактного датасета, и потом, мне надо спозиционировать его на сохраненную запись. Поэтому, я не могу выполнять явного преобразования в строку.
Добавлено @ 13:16
Хотя, конечно можно проверять тип поля и соответственно мудро конвертировать в строку. Но, это не есть хорошо. Все и без преобразования должно работать!

Добавлено @ 13:21
На самом деле, проблему преобразования variant(currency)->String можно продемонстрировать на более простом примере:
Код
{$APPTYPE CONSOLE}
uses
  SysUtils,Variants;
begin
  DecimalSeparator := '.';  WriteLn(VarToStr(1.23),' ',FloatToStr(1.23));
  DecimalSeparator := ',';  WriteLn(VarToStr(1.23),' ',FloatToStr(1.23));
  DecimalSeparator := '#';  WriteLn(VarToStr(1.23),' ',FloatToStr(1.23));
  Write('Press <Enter> key for close application ...');  ReadLn;
end.

Результат, при установленном в системе разделителе ',' :
Код
1,23 1.23
1,23 1,23
1,23 1#23
Press <Enter> key for close application ...


Это сообщение отредактировал(а) Петрович - 19.7.2005, 13:26


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
kobra
Дата 19.7.2005, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



а так не подоидет?
Код

program TestLocate;
{$APPTYPE CONSOLE}
uses
  SysUtils,ADODB,ActiveX,ComObj;

const
  DatabaseName    = 'c:\TestDb.mdb';
  CLASS_DBEngine :TGUID ='{00000100-0000-0010-8000-00AA006D2EA4}';

var
  db :TADOConnection;
  ds :TADODataSet;
  VARVARIANT: variant;
  VARSTRING: string;
begin
  WriteLn('initialization');

  try
    CoInitialize(Nil);
    db := TADOConnection.Create(Nil);
    ds := TADODataSet.Create(Nil);

    db.LoginPrompt := False;

    WriteLn('Create database');
    if  FileExists(DatabaseName)  then  DeleteFile(DatabaseName);
    Variant(CreateOleObject(ClassIDToProgID(CLASS_DBEngine)))
      .Workspaces[0]
        .CreateDatabase (DatabaseName, ';LANGID=0x0409;CP=1252;COUNTRY=0', 0);


    db.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0'
                          +';Data Source="'+DatabaseName+'"'
                          ;

    WriteLn('Create Table');
    db.Execute('CREATE TABLE Test (fld decimal(15, 4))');
    db.Execute('INSERT INTO Test VALUES (1.123)');
    db.Execute('INSERT INTO Test VALUES (2.123)');
    db.Execute('INSERT INTO Test VALUES (3.123)');

    

    WriteLn('Open table');
    ds.Connection := db;
    ds.CommandText := 'SELECT * FROM Test';
    ds.Open;

    WriteLn('DecimalSeparator -' + DecimalSeparator);
    DecimalSeparator := '.';
    WriteLn('New DecimalSeparator -' + DecimalSeparator);

    VARVARIANT := 2.123;
    str(VARVARIANT,VARSTRING);

    WriteLn('Show table');

    while not ds.Eof do begin
      WriteLn(ds.FieldByName('fld').AsString);
      ds.Next;
    end;

    Write('Locate 2.123 ');
    if  ds.Locate('fld',VARSTRING,[])  then
      WriteLn('success')
    else
      WriteLn('fail');


    Write('Locate ''2.123'' ');
    if  ds.Locate('fld','2.123',[])  then
      WriteLn('success')
    else
      WriteLn('fail');

  except on e :Exception do begin
    WriteLn('Error:');
    WriteLn(e.ClassName);
    WriteLn(e.Message);
    end;
  end;

  FreeAndNil(ds);
  FreeAndNil(db);
  CoUninitialize;
  Write('Press <Enter> key for close application ...');  ReadLn;
end.

PM MAIL   Вверх
Петрович
Дата 19.7.2005, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



А вот еще забавнее:
Код
{$APPTYPE CONSOLE}
uses
  SysUtils,Variants;
var
//  v :Currency;
  v :Double;
begin
  v := 1.23;
  DecimalSeparator := '.';  WriteLn(VarToStr(v),' ',FloatToStr(v));
  DecimalSeparator := ',';  WriteLn(VarToStr(v),' ',FloatToStr(v));
  DecimalSeparator := '#';  WriteLn(VarToStr(v),' ',FloatToStr(v));
  Write('Press <Enter> key for close application ...');  ReadLn;
end.

Если v имеет тип Currency, то результат будет:
Код
1,23 1.23
1,23 1,23
1,23 1#23
Press <Enter> key for close application ...
А если ее тип будет Double, то:
Код
1.23 1.23
1,23 1,23
1#23 1#23
Press <Enter> key for close application ...

smile


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
kobra
Дата 19.7.2005, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



ето ещо забавнее, но главное, наверняка тебе поможет. тоже самое что и в предидушем примере
Код

{$APPTYPE CONSOLE}
uses
  SysUtils,Variants;
var
  r :Currency;
  v :Double;
  S1, S2: string;

begin
  v := 1.23;
  r := 1.23;
  str(v,S1);
  str(r, S2);
  DecimalSeparator := '.';  WriteLn(VarToStr(v),' ',S1, ' ', VarToStr(r),' ',S2);
  DecimalSeparator := ',';  WriteLn(VarToStr(v),' ',S1, ' ', VarToStr(r),' ',S2);
  DecimalSeparator := '#';  WriteLn(VarToStr(v),' ',S1, ' ', VarToStr(r),' ',S2);
  Write('Press <Enter> key for close application ...');  ReadLn;
end.

поменял код, тогда промежуточныи вариант запостил

Это сообщение отредактировал(а) kobra - 19.7.2005, 13:50
PM MAIL   Вверх
Петрович
Дата 19.7.2005, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Я тащусь как нас разводят!
Вот выдержка их хелпа по функции Str (выделено мной):
Цитата
Str converts X to a string representation according to the Width and Decimals formatting parameters. The effect is like a call to Write except the resulting string is stored in S instead of being written to a text file.

Однако, выполняю такой код:
Код

var
  v :Variant;
  s :String;
begin
  v := 1.23;
  WriteLn(v);
  Str(v,s);
  WriteLn(s);
end.

и получаю:
Код
1,23
 1.23000000000000E+0000

Вот так. Добавить просто нечего smile
Добавлено @ 13:51
Цитата(kobra @ 19.7.2005, 14:45)
... но главное, наверняка тебе поможет ...

Увы нет. Как я уже писал, я заранее не знаю тип лежащий в варианте. В Str отреагирует не адекватно в том случае если ей передать вариант содержащий например tDateTime.

Добавлено @ 13:53
smile
Цитата
Вот так. Добавить просто нечего 
Добавлено @ 14:51

smile
Добавлено @ 13:55
На самом деле проблема только с Currency. Пэтому, конечно можно проверить что это именно он, и преобразовать его явно в строку с помощью FloatStr например.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
kobra
Дата 19.7.2005, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



я в предыдущем посте код поменял, но в принцыпе ты и без етого меня понял
Цитата
Добавить просто нечего smile 
smile

PM MAIL   Вверх
kobra
Дата 19.7.2005, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



Цитата
На самом деле проблема только с Currency. Пэтому, конечно можно проверить что это именно он, и преобразовать его явно в строку с помощью FloatStr например.
не понял.
и с денежным типом все в порядке, специално проверил переделав в таблице тип поля.
или я чтото не так понял?

PM MAIL   Вверх
Петрович
Дата 19.7.2005, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Пардон. Это я про VarToStr smile
Кстати, значения полей типа decimal(15, 4)) интерпретируются как Variant(Currency). Например, добавь после ds.Open; оператор:
Код

    Writeln(VarTypeAsText(VarType(ds.FieldByName('fld').Value)));



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
kobra
Дата 19.7.2005, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



даааааа...
сам танцует сам поет, да ешо и музыку сам заказывает smile
PM MAIL   Вверх
SergeBS
Дата 26.7.2005, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22



Петрович
Я тебе еще один косяк аналогичный изложу:
Берем numpad (ну это справа где буковок нет smile и вводим через него цифры. Так вот если ты не установишь DecimalSeparator в ".", то в зависимости от текущей раскладки ты либо сможешь ввести этот separator в DBEditе, либо нет (если на рус переключен). Это более прискорбно, чем программные проблемы с Select, которые можно обойти. Поэтому я при запуске проверяю значение разделителя, и если не мое, принудительно выставляю в ".". Самое залихватское при этом, что выставление сепаратора в "." на текущем запуске программы не скажется, только на следующем. С сответствующим моральным эффектом:
1 запуск - "ААААААААА! Программа не работает!" - "Покажи!" - 2 запуск - "Ой! Работает smile "
PM MAIL   Вверх
SergeBS
Дата 26.7.2005, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22




Блин, не привык еще здесь писать, не дописал.

Петрович
Совсем простой вопрос: у тебя что, автоинкрементных полей в MS SQL нет? Если есть - так сам понимаешь, как твоя проблема с поиском именно той записи, что ты правил, решается "на раз".
И чем букмарки не нравятся?
PM MAIL   Вверх
kobra
Дата 26.7.2005, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



Цитата(SergeBS @ 26.7.2005, 12:03)
И чем букмарки не нравятся?

попробуи такое.
установи букмарк, переиди на другую запис, измени поле сортировки и поиши по букмарку.
или удали какую то запис до букмарка.

Цитата(SergeBS @ 26.7.2005, 12:03)
Совсем простой вопрос: у тебя что, автоинкрементных полей в MS SQL нет? Если есть - так сам понимаешь, как твоя проблема с поиском именно той записи, что ты правил, решается "на раз".
искать то приходится не толко по клучу.

PM MAIL   Вверх
Петрович
Дата 26.7.2005, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(SergeBS @ 26.7.2005, 12:52)
Я тебе еще один косяк аналогичный изложу:
...

Ну и думаешь удивил smile. Эта фича уже давно известна. Здесь две причины:
1. Это мелкософт так в драйвер русской раскладки заложил. Если установлен режим "латинский" то эта клавиша продуцирует код символа '.' (точка), а если тек.регистр "русский" то продуцируется код ',' (запятая). Это если драйверок не патченный smile.
2. Компонент DBEdit построен на базе TCustomMaskEdit (я его просто ненавижу smile). А у него сделано фильтрование ввода.

Цитата(SergeBS @ 26.7.2005, 12:52)
Самое залихватское при этом, что выставление сепаратора в "." на текущем запуске программы не скажется, только на следующем.

Не там ставишь. Надо делать сразу после begin проргаммы, до первого Application.CreateForm.

Цитата(SergeBS @ 26.7.2005, 12:52)
Поэтому я при запуске проверяю значение разделителя, и если не мое, принудительно выставляю в ".".

Ну я это уже проходили. Раньше тоже так делали. Но, нехорошо пользователя напрягать. Если он хочет видеть в качестве разделителя ',', то плохо когда программа принудительно показывает (и требует от него ввода) разделителя '.'.

На самом деле, есть два решения.
Первое - патчить tMaskEdit. Там помимо этого есть еще ошибка (http://forum.vingrad.ru/index.php?showtopi...ndpost&p=476796)
Второе - вешать доп.обработку на свою форму. Это попутно поправить работу всех компонентов на форме, включая например DBGrid. Делается так:

1. У формы ставим свойство KeyPreview в True

2. У формы описываем поле LastKeyDown:
Код

...
  private
    LastKeyDown :Word;
...


3. Назначаем обработчик на событие OnKeyDown формы:
Код

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  LastKeyDown := Key;
end;


4. Назначаем обработчик на событие OnKeyPress формы:
Код

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  if  (LastKeyDown = VK_DECIMAL) and (Key in ['.',',']) then
    Key := DecimalSeparator;
end;


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



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Петрович
Дата 26.7.2005, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(SergeBS @ 26.7.2005, 13:03)
Совсем простой вопрос: у тебя что, автоинкрементных полей в MS SQL нет? Если есть - так сам понимаешь, как твоя проблема с поиском именно той записи, что ты правил, решается "на раз".
И чем букмарки не нравятся?

Это когда ты знаешь с какой таблицей работаешь.
Я столкнулся с этим в процедуре работающей с абстрактным tDataSet о котором ничего неизвестно. В этой процедуре нужно закрыть датасет и потом открыть его снова. При этом, надо по возможности сохранить позицию в датасете на той-же записи на которой он был спозиционирован до закрытия.
А закладки (букмарки) не годятся. В большинстве наследников tDataSet, закладки реализуются в виде порядкового номера записи в наборе. Соответственно, поскольку перечень записей и даже их количестко в таблице может измениться после close/open, то и закладка может спозиционировать не туда. Проверено практикой. Где то в хелпах даже читал о том что значение Bookmark действительно только пока Dataset не закрыт, хотя, что-то сходу не нашел где.




--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Akella
Дата 11.8.2005, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



Цитата
действительно только пока Dataset не закрыт

не всегда, я меняю количество товара, например, закрываю НД, открываю и закладка позиционируется нормально. Да записей я не добавляю в этом случае, поэтому, наверное, и нормально работает.
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.1006 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.