Перейти к содержанию
Fire Monkey от А до Я

Поиск сообщества

Показаны результаты для 'RecordCount'.

  • Поиск по тегам

    Введите теги через запятую.
  • Поиск по автору

Тип контента


Форумы

  • Общие вопросы
    • Анимация
    • Графика
    • Стили
    • Базы данных и REST
    • Компоненты
    • Положение, размеры, выравнивание
    • Работа с текстом
    • Приложение и формы
    • Отладка
    • Развертывание приложений
    • Вопросы по языку Object Pascal и RTL
    • Общая информация о TControl
    • События
    • Прочие вопросы
  • Вопросы по платформам
    • Android
    • iOS
    • OSX
    • Windows
    • Windows Phone
    • Linux
  • Вопросы по использованию RAD Studio
    • Лицензирование
    • Сборка проектов
    • Multi-Device Designer
    • Редактор кода
    • Вопросы
  • Обучение
    • Основная информация
    • Вопросы
    • Отзывы
  • Поиск специалистов по FireMonkey
    • Консультации
    • Ищу подрядчика
  • Дополнительные ресурсы по FireMonkey
    • Сторонние компоненты
    • Приложения, написанные с использованием FireMonkey
    • Примеры
    • Руководства
    • Шаблоны
    • Статьи и заметки
    • Информация о версиях RAD Studio
    • Новости
  • Организация работы данного форума

Поиск результатов в...

Поиск контента, содержащего...


Дата создания

  • Начало

    Конец


Дата обновления

  • Начало

    Конец


Фильтр по количеству...

Регистрация

  • Начало

    Конец


Группа


AIM


MSN


Сайт


ICQ


Yahoo


Jabber


Skype


StackOverflow


Защита от ботов


Город


Интересы

  1. Подскажите пожалуйста почему когда я пытаюсь заполнить ComboBox из базы SQLite в мобильном приложении для Android вот так: //заполняем ComboBox двигателя FDQuery_ComboBox.Active:=False; FDQuery_ComboBox.SQL.Clear; FDQuery_ComboBox.SQL.Add('SELECT Dvig_ob FROM TabSR '); FDQuery_ComboBox.Active:=True; //ShowMessage('Количество строк: '+IntToStr(FDQuery_ComboBox.RecordCount)); for i:=1 to FDQuery_ComboBox.RecordCount do Begin FDQuery_ComboBox.RecNo := i; ComboBox_Engin.Items.Add(FDQuery_ComboBox.Fields[0].AsString); End; в FDQuery_ComboBox.RecordCount всего ровно 50 позиций хотя в таблице TabSR 288 строк???? СпасиБО. С Уважением.
  2. еще хороший тон прилагать хотя бы краткую инструкцию - что надо переименовать, куда поместить путь к базе, и что нажать, чтобы запустить программу и потом что нажать, чтобы получить ошибку. еще раз обращаю внимание, что для того, чтобы вам помогали, нужно как-то позаботиться о том, кто должен почему-то разбираться в вашем коде. Он не отформатирован даже. Есть волшебство Ctrl+D или Ctrl+W в cnWizard, которые это даже делают автоматически за вас. я двумя постами выше написал, как должен выглядеть запрос. У вас совершенно не такой. Если вы хотите делать по-своему, делайте, но я тогда при чем тут? самое главное. Даже неправильный запрос нужно открыть! FDQuery4.SQL.Clear; FDQuery4.SQL.Add('SELECT * FROM usersbase'); FDQuery4.SQL.Add('WHERE Login='+Login); Password1:=FDQuery1.FieldByName('Password').AsString; Group1:=FDQuery1.FieldByName('Group').AsString; Other1:=FDQuery1.FieldByName('Other').AsString; где тут открытие ? в какой момент программа должна обратиться к серверу? ну и ясно, что мой текст по ссылке вы не читали. потому что строковые константы хотя бы нужно оборачивать кавычками, но вообще речь шла о параметрах, которые позволяют и этого не делать. я не стал разбираться в хитростях остальной вашей логики, там сомнительное использование непонятно где объявленных внешних переменных и какие-то неизвестные науке операции с числами и строками из базы. еще совершенно неясно, почему запрос идет в FDQuery4, а поля вы запрашиваете в FDQuery1 ??? главная идея - вам юзер ввел логин и пароль. вы запросили сервер, есть ли юзер с таким логином и паролем. сервер либо нашел его, либо нет. если нет, то все переменные неплохо бы сбросить в пусто. сам запрос помещен в компонент в дизайн-тайме, не нужно его каждый раз писать заново итого function TForm4.verifikation(Login, Password: string): string; begin result := ''; Group1 := ''; Other1 := ''; FDQuery4.Close(); FDQuery4.ParamByName('login').AsString := login; FDQuery4.ParamByName('password').AsString := password; FDQuery4.Open(); if FDQuery4.RecordCount = 0 then exit; I := 4; Password1 := Password; Group1 := FDQuery4.FieldByName('Group').AsString; Other1 := FDQuery4.FieldByName('Other').AsString; if Group1 <> 'Admin' then I := I - 1 else Result := '"' + inttostr(I) + '"' + Other1 + '"'; if Group1 <> 'moder' then I := I - 1 else Result := '"' + inttostr(I) + '"' + Other1 + '"'; end;
  3. Здравствуйте! Блоб параметры в процедурах PostgreSQL победить не удалось, а вот та же функциональность через Блоб-поля TFDQuery была достигнута. В целом такой вариант более универсален. void __fastcall TNNConfig::SaveToDB() { if ( Connection && !Connection->Connected ) return; TMemoryStream* ms = new TMemoryStream(); fFiler = new TNNTextStream( ms ); try { SaveFilerFromUserEvent(); std::unique_ptr< TFDQuery > quReg( new TFDQuery( this ) ); std::unique_ptr< TFDTransaction > trReg( new TFDTransaction( this ) ); quReg->Connection = Connection; trReg->Connection = Connection; quReg->Transaction = trReg.get(); String RK = RegistryKey(); Connection->StartTransaction(); try { quReg->SQL->Text = "SELECT \"UserRegKey\", \"UserData\" FROM \"UserReg\" where \"UserRegKey\" = :UserRegKey_"; quReg->Params->Items[ 0 ]->DataType = ftString; quReg->Params->Items[ 0 ]->AsString = RK; quReg->Open(); if ( quReg->RecordCount == 0 ) { quReg->Insert(); quReg->Fields->Fields[ 0 ]->AsString = RK; } else quReg->Edit(); TBlobField *bf = ((TBlobField *)(quReg->Fields->Fields[ 1 ])); bf->LoadFromStream( Filer ); quReg->Post(); Connection->Commit(); } catch ( ... ) { Connection->Rollback(); } } __finally { delete fFiler; fFiler = nullptr; } } bool __fastcall TNNConfig::LoadFromDB() { if ( Connection && !Connection->Connected ) return false; bool B = false; std::unique_ptr< TFDQuery > quReg( new TFDQuery( this ) ); std::unique_ptr< TFDTransaction > trReg( new TFDTransaction( this ) ); quReg->Connection = Connection; trReg->Connection = Connection; quReg->Transaction = trReg.get(); quReg->SQL->Text = "SELECT \"UserRegKey\", \"UserData\" FROM \"UserReg\" where \"UserRegKey\" = :UserRegKey_"; quReg->Params->Items[ 0 ]->DataType = ftString; quReg->Params->Items[ 0 ]->AsString = RegistryKey(); quReg->Open(); if ( quReg->RecordCount == 1 ) { TBlobField *bf = ((TBlobField *)(quReg->Fields->Fields[ 1 ])); bf->SaveToStream( Filer ); B = true; } return B; } Вопрос закрыт! Спасибо! С уважением, Навадвипа Чандра дас.
  4. СпасиБО SLAVZ. Попробую. Может Вам пригодится я вот так вышел и положения: Сначала: //выбираем фото из галереи устройства procedure TForm_haracteristik.TakePhotoFromLibraryAction1DidFinishTaking( Image: TBitmap); begin Image_ФотоХаракДвиг.Bitmap.Assign(Image); end; Потом вношу в Базу: //ввести харак-ку procedure TForm_haracteristik.Button_ВвестиClick(Sender: TObject); begin if Edit_НазваниеХарактеристики.Text='' then begin ShowMessage('Вы не ввели название характеристики.'); Abort; end; //проверяем наличие дубля названия характеристики: FDQuery_Engin.Open; FDQuery_Engin.SQL.Clear; FDQuery_Engin.SQL.Add('select * from Tab_Harak_Engin where Name_Harak = ' + #39+ Edit_НазваниеХарактеристики.Text +#39); FDQuery_Engin.Active:=True; if FDQuery_Engin.RecordCount > 0 then begin ShowMessage('Такое название уже есть !'); Abort; end else begin Try FDQuery_Engin.Active:=False; FDQuery_Engin.SQL.Clear; FDQuery_Engin.SQL.Add('SELECT * FROM Tab_Harak_Engin ORDER BY Name_Harak' ); FDQuery_Engin.Active:=True; //вставляем строку новой модели: FDQuery_Engin.Insert; FDQuery_Engin.FieldByName('Name_Harak').AsString:=Edit_НазваниеХарактеристики.Text; //заносим в поток файл картинки IconStream:=TMemoryStream.Create; Image_ФотоХаракДвиг.Bitmap.SaveToStream(IconStream); IconStream.Position := 0; (FDQuery_Engin.FieldByName('Harak_Engin') as TBlobField).LoadFromStream(IconStream); IconStream.Free; FDQuery_Engin.Post; ShowMessage('Введено.'); Except ShowMessage('Ошибка ввода в базу.'); End; end; //перезагружаем Boxы Box_НазвХарДвиг.Clear; Box_НазвХарДвигУдаление.Clear; FDQuery_ComboBox_Engin.Active:=False; FDQuery_ComboBox_Engin.SQL.Clear; FDQuery_ComboBox_Engin.SQL.Add('SELECT Name_Harak FROM Tab_Harak_Engin ORDER BY Name_Harak'); FDQuery_ComboBox_Engin.Active:=True; for i:=1 to FDQuery_ComboBox_Engin.RecordCount do begin FDQuery_ComboBox_Engin.RecNo:=i; Box_НазвХарДвиг.Items.Add(FDQuery_ComboBox_Engin.FieldByName('Name_Harak').AsString); Box_НазвХарДвигУдаление.Items.Add(FDQuery_ComboBox_Engin.FieldByName('Name_Harak').AsString); end; end; Так удаляю из базы если надо: //удалить procedure TForm_haracteristik.Button_УдалитьClick(Sender: TObject); begin if Box_НазвХарДвигУдаление.ItemIndex=-1 then begin ShowMessage('Вы не выбрали имя характеристики.'); Abort; end; TX:=''; TX:=Box_НазвХарДвигУдаление.Selected.Text; //становимся на эту позицию FDQuery_Engin.Active:=False; FDQuery_Engin.SQL.Clear; FDQuery_Engin.SQL.Add('SELECT * FROM Tab_Harak_Engin where Name_Harak= '+#39+TX+ #39); FDQuery_Engin.Active:=True; Try FDQuery_Engin.Delete; ShowMessage('Удалено.'); Except ShowMessage('Не удалось удалить.'); End; //перезагружаем Boxы Box_НазвХарДвиг.Clear; Box_НазвХарДвигУдаление.Clear; FDQuery_ComboBox_Engin.Active:=False; FDQuery_ComboBox_Engin.SQL.Clear; FDQuery_ComboBox_Engin.SQL.Add('SELECT Name_Harak FROM Tab_Harak_Engin ORDER BY Name_Harak'); FDQuery_ComboBox_Engin.Active:=True; for i:=1 to FDQuery_ComboBox_Engin.RecordCount do begin FDQuery_ComboBox_Engin.RecNo:=i; Box_НазвХарДвиг.Items.Add(FDQuery_ComboBox_Engin.FieldByName('Name_Harak').AsString); Box_НазвХарДвигУдаление.Items.Add(FDQuery_ComboBox_Engin.FieldByName('Name_Harak').AsString); end; end; Так просматриваю: //просмотр картинки procedure TForm_haracteristik.ComboBox_НазвХарДвигChange(Sender: TObject); begin //становимся на эту позицию //FDQuery_Engin.Locate('Name_Harak',TX,[loPartialKey, loCaseInsensitive]); FDQuery_Engin.Active:=False; FDQuery_Engin.SQL.Clear; FDQuery_Engin.SQL.Add('SELECT * FROM Tab_Harak_Engin where Name_Harak= '+#39+Box_НазвХарДвиг.Selected.Text+ #39); FDQuery_Engin.Active:=True; Try //заносим в поток файл картинки IconStream:=TMemoryStream.Create; (FDQuery_Engin.FieldByName('Harak_Engin') as TBlobField).SaveToStream(IconStream); If IconStream.Size<>0 then begin IconStream.Position:=0; Image_Просмотр.Bitmap.LoadFromStream(IconStream); IconStream.Free; end else begin ShowMessage('Нет фото.'); Exit; end; Except ShowMessage('Не удалось загрузить фото.'); End; end;
  5. Приветствую! Некорректно отрабатывает поток в Андройде, а именно мерцания экрана procedure Tspotok.Add; begin Form1.foot.Add(Form1.ListBox1); end; procedure Tspotok.Add2; begin Form1.st.Add(Form1.ListBox1); end; procedure Tspotok.Add3; begin Form1.st.ListImage.Items[Form1.st.ListvName.Count-1].Bitmap.LoadFromStream(BlobStream); end; procedure Tspotok.Execute; var FDConnection1: TFDConnection; FDQuery1: TFDQuery; FDPhysSQLiteDriverLink1: TFDPhysSQLiteDriverLink; FDGUIxWaitCursor1: TFDGUIxWaitCursor; j,i:integer; begin FDConnection1:=TFDConnection.Create(nil); FDConnection1.DriverName:='SQLite'; FDPhysSQLiteDriverLink1:=TFDPhysSQLiteDriverLink.Create(nil); FDGUIxWaitCursor1:=TFDGUIxWaitCursor.Create(nil); FDQuery1:=TFDQuery.Create(nil); {$IFDEF ANDROID} FDConnection1.Params.Values['Database'] := TPath.Combine(TPath.GetDocumentsPath, 'base.db'); {$ENDIF} {$IFDEF MSWINDOWS} FDConnection1.Params.Values['Database'] :='E:\Embarcadero\Studio\Projects\NANDBOOK_TWO\base.db'; {$ENDIF} FDConnection1.Connected:=TRUE; for I := 0 to 16 do begin FDQuery1.SQL.Text:='SELECT * FROM '+Form1.NameBaseconst+' WHERE name LIKE "'+Form1.v+'%"'; FDQuery1.Connection:=FDConnection1; FDQuery1.Active := True; FDQuery1.Open; Synchronize(Add); Form1.foot.ListvName.Items[Form1.foot.List.Count-1].Text:=Form1.NameB; if FDQuery1.RecordCount=0 then begin Form1.foot.List.Items[Form1.foot.List.Count-1].Visible:=false; end; if not FDQuery1.IsEmpty then begin //Log.d('LOG-FDQuery1.RecordCount='+FDQuery1.RecordCount.ToString()); for j := 0 to FDQuery1.RecordCount-1 do begin Synchronize(Add2); Form1.st.List.Items[Form1.st.ListvName.Count-1].Parent:= Form1.ListBox1; Form1.st.ListTag.Items[Form1.st.ListvName.Count-1].Text:=IntToStr(Form1.ListBox1.Count-1); Form1.st.ListvName.Items[Form1.st.ListvName.Count-1].Text :=FDQuery1.FieldByName('name').AsString; Form1.st.ListBase.Items[Form1.st.ListvName.Count-1].Text :=Form1.NameBaseconst; Form1.st.ListID.Items[Form1.st.ListvName.Count-1].Text :=FDQuery1.FieldByName('id').AsString; BlobStream:=TStream.Create; BlobStream := FDQuery1.CreateBlobStream(FDQuery1.FieldByName('image'),TBlobStreamMode.bmRead); Synchronize(Add3); FDQuery1.Next; end; end; FDQuery1.Close; FDQuery1.Active := false; end; FDConnection1.Connected:=false; end; end. А в осном unite var QW:Tspotok; .. QW:=Tspotok.Create(true); QW.FreeOnTerminate:=true; QW.Resume;
  6. Всем привет. Вообщем пытаюсь синхронизировать свою локальную базу с сервером, использую при этом Restrequest,все идет нормально но только приложение зависает на время цикла. В цикле идет перебор все данных в локальной базе и заносится по ссылке в базу. Пытался сделать в потоке но выскакивает ошибка "Argument errore", а без потока не выскакивает. Есть решение для улучшения скорости или хотя бы убрать зависания приложения? спасибо за ранее за вашу помощь. var aggiornarichiesta: TJSONObject; i,b: Integer; a:TStream; begin FDTable1.First; for i := 0 to FDTable1.RecordCount do begin if RESTRequest1.Response.StatusCode = 200 then begin try RESTRequest1.ClearBody; RESTClient1.BaseURL := 'http://localhost/loman/dati.php'; RESTRequest1.Execute; aggiornarichiesta := TJSONObject.Create; aggiornarichiesta.AddPair('id', FDTable1ID.Text); aggiornarichiesta.AddPair('Materiale', FDTable1.FieldByName('Materiale').AsString); aggiornarichiesta.AddPair('Descripzione', FDTable1.FieldByName('Descripzione').AsString); aggiornarichiesta.AddPair('Quantita', FDTable1.FieldByName('Quantita') .AsString); aggiornarichiesta.AddPair('Treno', FDTable1.FieldByName('Treno') .AsString); aggiornarichiesta.AddPair('Discorta', FDTable1.FieldByName('Discorta') .AsString); aggiornarichiesta.AddPair('Commento', FDTable1.FieldByName('Commento') .AsString); aggiornarichiesta.AddPair('Creatoda', FDTable1.FieldByName('Creatoda') .AsString); aggiornarichiesta.AddPair('Ordinato', FDTable1.FieldByName('Ordinato') .AsString); RESTClient1.BaseURL := 'http://localhost/loman/Product/update.php'; RESTRequest1.ClearBody; RESTRequest1.AddBody(aggiornarichiesta.ToString, ContentTypeFromString('application/json')); RESTRequest1.Execute; FDTable1.Next; RESTRequest1.ClearBody; RESTClient1.BaseURL := 'http://localhost/loman/dati.php'; RESTRequest1.Execute; finally RESTRequest1.DisposeOf; end; end; end;
  7. Спасибо за этот совет, мне он помог наконец-то успешно запустить мой android сервис, который сохряняет в БД sqlite некоторые данные из инета. Но есть другая проблема. Я запускаю свое мобильное приложение, нажимаю кнопочку и запускается фоновый сервис. Пока я нахожусь в главном приложении, сервис работает, я вижу как обновляются данные в таблицах. Все хорошо. Если закрыть приложение, то сервис работает в фоне - тоже все ок. Но если я попытають снова запустить приложение, пока сервис в фоне делает выборку или записывает данные в таблицу, то мое приложение не запускается - я вижу черный экран. Как только сервис закончил работать с таблицами и сделал небольшую паузу на 5 минут, в этот промежуток времени я могу окрыть свое приложение. Вывод такой: сервис блокирует мою базу данных пока с ней работает. Как сделать паралельный доступ к БД и из приложения и из сервиса? Сервис использует простую схему работы: fdquery1.SQL.Text := 'select * from table1' fdquery1.Open for i:= 0 to fdquery1.RecordCount -1 do begin // здесь я считываю поля таблицы(например, ссылки на сайты), затем лезу по каждому урлу на сайт и, если на нем появились новые данные, то сохраняю их в Table2. end; Я так понимаю, пока у меня fdquery1.Open, мое приложение не запустится, поскольку база заблокирована сервисом. Как это лечится? FDСonnection LockingMode = imNormal FDQuery cmdExecMode = amNonBlocking
  8. Ознакомьтесь с FireDAC.Stan.Option.TFDFetchOptions.RecordCountMode. И начните уже пользоваться поиском на форуме... Не один раз обсуждалась эта тема Показаны результаты для 'RecordCount' p.s. Тему перенёс в подходящий раздел.
  9. Использую БД SQLite, количество записей перевалило за 2000. Понадобилось перебрать все записи и сравнить с каждую запись с другим массивом данных. Загрузить все данные, а это 2000 с лишним записей сразу не позволяет система, просто ничего не происходит (процедура не исполняется). Поэтому свойство FetchOption.RowsetSize установил 500, свойство FetchOption.Mode установлено в fmOnDemand, т.е.когда обрабатывается порция данных по документации должна быть получена следующая порция данных и так до конца. Однако, на практике при такой конструкции при получении данных, количество данных (RecordCount) приравнивается к св-ву RowsetSize и выводит только 500 записей, а цикл While почему-то не работает, просто ничего не происходит. Как вывести полный объем данных? var DBArray: TStringList; FQuery: TMySQLiteQuery; ........ SQL := 'SELECT * FROM FileStore'; FQuery.SelectQuery(SQL); //while (not FQuery.Eof) do for j := 0 to FQuery.RecordCount - 1 do begin AData := FQuery.Fields.FieldByName('FileName').AsString; DBArray.Append(AData); FQuery.Next; end; ShowMessage(IntToStr(DBArray.Count)); .......
  10. RecordCount - это количество зафетченных на клиента записей, а не кол-во записей датасета First; Last; конечно приведут RecordCount в правильное состояние, но вы 10 раз об этом пожалеете, если на мобилу приедут все ваши 100500 записей, а нужно было только 100
  11. Query.Last; //Переходим к последней записи в выборке X := Query.RecordCount; //Здесь RecordCount уже выдаст правильное количество записей Query.First; // Возвращаемся к первой записи.
  12. Только если Вы сделаете TThread.Synchronize(TThread.CurrentThread, {тут процедура отрисовки вашего bitmap}) из того самого "второстепенного" потока. создаю поток procedure TfrmMain.SetInitializationReadDB(iExerciseId: integer); begin ReadAction := TReadActionFromDB.Create(); ReadAction.onReadAction := ReadActionDb; ReadAction.ExId := iExerciseId; ReadAction.Start; end; процедура Exrcute procedure TReadActionFromDB.Execute; var qr: ISyncQueryResult; begin try fRecordsCount := 0; while not Terminated do begin if ExId > 0 then begin qr := AppData.Select('log', [TScriptGetParameterHelper.Create('exercise', ExId)]); if qr.DataSet.RecordCount > fRecordsCount then begin // если появились новые записи qr.DataSet.First; qr.DataSet.MoveBy(fRecordsCount); while not qr.DataSet.Eof do begin // время события fTime := qr.DataSet.FieldByName('VTIME').AsString;; // название события fActionName := qr.DataSet.FieldByName('DESCRIP_ACTION').AsString; // id действия if not qr.DataSet.FieldByName('ID_ACTION').IsNull then fActionID := qr.DataSet.FieldByName('ID_ACTION').AsInteger else fActionID := 0; // номер записи fRecordNumber := qr.DataSet.RecNo; // колличество всех записией fRecordsCount := qr.DataSet.RecordCount; Synchronize(Sync); // Queue(Sync); // Sleep(100); qr.DataSet.Next; end; // Sleep(500); end; end; end; except on E: Exception do DoReadError(E.ClassName + ' ошибка с сообщением : ' + E.Message); end; end; procedure TReadActionFromDB.Sync; begin if Assigned(fonReadAction) then fonReadAction(Self, fTime, fActionName, fRecordNumber, fActionID); end; Кал-бак функцию для отрисовки procedure TfrmMain.ReadActionDb(Sender: TObject; const sTime, sActionName: string; const RecordNumber, ActionID: integer); var Item: TListBoxItem; aFileStream: TFileStream; aBitmap: TBitmap; begin Item := TListBoxItem.Create(nil); Item.Index := 0; // Item.Parent := lbLogActions; Item.Height := 60; Item.Margins.Top := 10; Item.StyleLookup := 'listboxitemaction'; Item.Tag := ActionID; Item.StylesData['timeaction'] := SecToTime(sTime); Item.StylesData['labelaction'] := sActionName; // Item.StylesData['imageaction'] := '.\images\ScenarioImage\actions\' + IntToStr(ActionID) + '.png'; aFileStream := TFileStream.Create('.\images\ScenarioImage\actions\' + IntToStr(ActionID) + '.png', fmOpenRead); try if (aFileStream.Size > 0) then begin aBitmap := TBitmap.CreateFromStream(aFileStream); Item.StylesData['imageaction'] := TValue.From<TBitmap>(aBitmap); Item.StylesData['imageaction.visible'] := True; Item.ItemData.Bitmap.Assign(aBitmap); end; finally FreeAndNil(aFileStream); end; lbLogActions.InsertObject(0, Item); end;
  13. procedure TfrmPrincipal.AdicionarSomenteOfertasLista; var Tarefa: ITask; begin dmDadosLocais.qryListaSomenteOfertas.Active := False; dmDadosLocais.qryListaSomenteOfertas.ParamByName('IDOFFSET').AsInteger := TotalSomenteOfertasOFFSET; dmDadosLocais.qryListaSomenteOfertas.Active := True; dmDadosLocais.qryListaSomenteOfertas.First; Tarefa := TTask.Create( procedure() var strOferta, strEmpresa, strSloganEmpresa, strIDOferta: string; // LItem: TListViewItem; //Lista de Imagens ItemFolder: TListItemImage; Background: TListItemImage; LogoMarca: TListItemImage; IconeCupom: TListItemImage; IconeCurtidas: TListItemImage; // Tratablhar com imagens ImgStream, ImgStreamLogoEmpresa: TStream; ImagemAlterada: TBitmap; ImagemBackGround: TBitmap; ImagemLogoMarca: TBitmap; ImagemCupom: TBitmap; UsarCupom: Boolean; //Posicionamento ItemTituloOferta, ItemEmpresa, ItemSlogan, ItemNumeroCurtidas: TListItemText; vKoef: Single; AlturaImagem: Single; AvailableWidth: Single; AlturaLvOfertas: Single; Linha: Single; //Texto curtidas strCurtidas: string; begin if dmDadosLocais.qryListaSomenteOfertas.RecordCount > 0 then begin LoadCarregandoSomenteOfertas.Visible := True; lvSomenteOfertas.BeginUpdate; try while not dmDadosLocais.qryListaSomenteOfertas.Eof do begin strOferta := dmDadosLocais.qryListaSomenteOfertas.FieldByName('oferta').AsString; strEmpresa := dmDadosLocais.qryListaSomenteOfertas.FieldByName('empresa').AsString; strIDOferta := dmDadosLocais.qryListaSomenteOfertas.FieldByName('id').AsString; strSloganEmpresa := dmDadosLocais.qryListaSomenteOfertas.FieldByName('slogan').AsString; ImgStream := dmDadosLocais.qryListaSomenteOfertas.CreateBlobStream(dmDadosLocais.qryListaSomenteOfertas.FieldByName('img_media'), TBlobStreamMode.bmRead); ImgStreamLogoEmpresa := dmDadosLocais.qryListaSomenteOfertas.CreateBlobStream(dmDadosLocais.qryListaSomenteOfertas.FieldByName('logomarca'), TBlobStreamMode.bmRead); //Controle de Cupom if dmDadosLocais.qryListaSomenteOfertas.FieldByName('usar_cupom').AsBoolean = True then UsarCupom := True else if dmDadosLocais.qryListaSomenteOfertas.FieldByName('usar_cupom').AsBoolean = False then UsarCupom := False; TThread.Synchronize(TThread.CurrentThread, procedure() begin AvailableWidth := lvSomenteOfertas.Width - lvSomenteOfertas.ItemSpaces.Left - lvSomenteOfertas.ItemSpaces.Right; ImagemAlterada := TBitmap.Create; ImagemAlterada.LoadFromStream(ImgStream); {Tamanho e Posicionamento} if Handle = nil then exit; // on Android without this user will get Access Violation vKoef := AvailableWidth / ImagemAlterada.Width; AlturaImagem := ImagemAlterada.Height * vKoef; LItem := lvSomenteOfertas.Items.Add; LItem.Height := (Round(AlturaImagem) + 5 + 22 + 5 + 40 + 3 + 20 + 30); //Atribui valores LItem.Data['Oferta'] := strOferta; LItem.Data['Empresa'] := strEmpresa; LItem.Data['IDOferta'] := strIDOferta; LItem.Data['SloganEmpresa'] := strSloganEmpresa; strCurtidas := dmDadosLocais.NumeroDeCurtidasFEED(StrToInt(strIDOferta)); LItem.Data['NumeroCurtidas'] := strCurtidas; if strCurtidas.IsEmpty = True then LItem.Data['IconeCurtida'] := 0 else if strCurtidas.IsEmpty = False then LItem.Data['IconeCurtida'] := 1; //Folder ItemFolder := TListItemImage(LItem.View.FindDrawable('Folder')); ItemFolder.OwnsBitmap := True; ItemFolder.Bitmap := ImagemAlterada; ImagemAlterada.Free; ItemFolder.Height := AlturaImagem; Background := TListItemImage(LItem.View.FindDrawable('Background')); Background.Visible := False; //LogoEmpresa LogoMarca := TListItemImage(LItem.View.FindDrawable('LogoEmpresa')); ImagemLogoMarca := TBitmap.Create; LogoMarca.OwnsBitmap := True; ImagemLogoMarca.LoadFromStream(ImgStreamLogoEmpresa); LogoMarca.Bitmap := ImagemLogoMarca; ImagemLogoMarca.Free; //Icone do Cupom IconeCupom := TListItemImage(LItem.View.FindDrawable('iconeCUPOM')); ImagemCupom := TBitmap.Create; IconeCupom.OwnsBitmap := True; if UsarCupom = True then ImagemCupom := imgIconeCupom.Bitmap else if UsarCupom = False then ImagemCupom := imgIconeSemCupom.Bitmap; IconeCupom.Bitmap := ImagemCupom; ImagemCupom.Free; //Localiza Objetos IconeCurtidas := TListItemImage(LItem.View.FindDrawable('IconeCurtida')); ItemTituloOferta := TListItemText(LItem.View.FindDrawable('Oferta')); ItemEmpresa := TListItemText(LItem.View.FindDrawable('Empresa')); ItemSlogan := TListItemText(LItem.View.FindDrawable('SloganEmpresa')); ItemNumeroCurtidas := TListItemText(LItem.View.FindDrawable('NumeroCurtidas')); // Posiciona Objetos nos controles Linha := 5; //Linha 1 - Dados da empresa LogoMarca.PlaceOffset.Y := Linha; ItemEmpresa.PlaceOffset.Y := Linha; ItemEmpresa.PlaceOffset.X := 60; ItemSlogan.PlaceOffset.Y := Linha + 21; ItemSlogan.PlaceOffset.X := 60; //Linha 2 - Folder da Oferta Linha := Linha + LogoMarca.Height + 7; ItemFolder.PlaceOffset.Y := Linha; //Linha 3 - Titulo da oferta Linha := Linha + AlturaImagem + 5; ItemTituloOferta.PlaceOffset.Y := Linha; //Linha 4 - Número de Curtidas Linha := Linha + ItemTituloOferta.Height + 3; ItemNumeroCurtidas.PlaceOffset.Y := Linha; IconeCurtidas.PlaceOffset.Y := Linha; end); dmDadosLocais.qryListaSomenteOfertas.Next; end; finally lvSomenteOfertas.EndUpdate; // if TotalSomenteOfertasOFFSET = 0 then // TThread.Synchronize(nil, RepintarOfertasDesalinhadas); TotalSomenteOfertasOFFSET := TotalSomenteOfertasOFFSET + 10; TThread.Synchronize(TThread.CurrentThread, procedure() begin if TotalSomenteOfertasOFFSET = 10 then RepintarOfertasDesalinhadas(lvSomenteOfertas); LoadCarregandoSomenteOfertas.Visible := False; end); end; end; end); Tarefa.Start; end;
  14. это очень нехорошо. должно быть query.Open; grid.RowCount:=query.RecordCount; // это не очень верно, но пока ладно... n:=0; while not query.eof do begin FillRow(n); query.Next; inc(n); end; query.Close; ну и да, соглашусь. даже секунда, это многовато...
  15. kraporkin, спасибо! Проблема не решилась. Изначально я убрал LiveBindings , т.к. думал тормозит заливка грида из-за него. А заливка даже ручная, какую я написал всё-равно тормозит и заливает в грид секунд 15-20... MainForm.StringGrid1.BeginUpdate; try MainForm.qClients.First; for i:=0 to MainForm.qClients.RecordCount-1 do begin MainForm.StringGrid1.RowCount:=MainForm.StringGrid1.RowCount+1; MainForm.StringGrid1.Cells[0, i] :=MainForm.qClients.FieldByName('FAM').AsString; MainForm.StringGrid1.Cells[1, i] :=MainForm.qClients.FieldByName('IM').AsString; MainForm.StringGrid1.Cells[2, i] :=MainForm.qClients.FieldByName('ID').AsString; MainForm.zqClients.Next; end; finally MainForm.StringGrid1.EndUpdate; end;
  16. Grid2.BeginUpdate; try for i:=0 to qClients.RecordCount-1 do begin XXX:=qClients.Fields[0].AsString; qClients.Next; end; finally Grid2.EndUpdate; end; Что должно быть вместо XXX?
  17. Если VCL там есть DBGrid, MyDataSource указать, все само отрисуется. В FMX по сути тоже должен быть способ, типа LiveBindings. Можно рисовать в рукопашную for ( int i = 0; i < fquery->RecordCount; i++ ) { // пройти по записям fquery->RecNo = i + 1; // получить массив данных TByteDynArray da = fquery->Fields->FieldByNumber(0)->AsBytes; // скопировать массив в Stream, // возможно есть другие способы скопировать TByteDynArray в TStream, я на вскидку скопировал побайтно TMemoryStream *ms = new TMemoryStream; ms->SetSize( da.Length ); // занять область под копирование char *ms_data = (char*)ms->Memory; // именованый указатель на область память for( int j = 0; j < da.Length; i++ ) char[i] = da[i]; // копирование побайтно в цикле TBitmap *b = new TBitmap; b->LoadFromStream( ms ); // здесь в битмап уже должно быть изображение delete ms; delete b; }
  18. для заполнения листвью юзаю подобное решение procedure TFVisit.bListViewFill(LV: TListView; FDSource: TFDQuery; TextField, DetailField, TagField: string; IsClear: boolean); var i, index: integer; item: TListViewitem; begin if LV.Selected <> nil then index:= LV.Selected.Index else index:= -1; if FDSource.IsEmpty then begin // ShowMessage('Нет данных!'); LV.Items.Clear; exit; end; if IsClear then LV.Items.Clear; LV.BeginUpdate; try for i:= 1 to FDSource.RecordCount do begin FDSource.RecNo:= i; item:= LV.Items.Add; item.Text:= FDSource.FieldByName(TextField).AsString; item.Detail:= FDSource.FieldByName(DetailField).AsString; // item.Bitmap.Assign(...) item.Tag:= FDSource.FieldByName(TagField).AsInteger; end; finally LV.EndUpdate; end; if index = -1 then exit; if (LV.Items.Count >= index) then LV.ItemIndex:= index; end; ну и заполняю tbPriceList: TFDQuery; . . . tbPriceList.Open; //фильтрованный по необходимым условиям bListViewFill(ListView1, tbPriceList, 'Name', 'LCP_Qty', 'ProductId', True); tbPriceList.Close; Мне часто приходится работать с листвью где text, detail и tag... но иногда приходится юзать остальной функционал листвью: хидеры-шмидеры, имейджи и т.д. но это уже другой вопрос
  19. В общем, потестил малость, набросал приложение, сканирующее System32. Дано: 3181 файл (+1 новый для проверки) база с двумя одинаковыми таблицами (по два столбца(id, FileName) в каждой) Результаты: Проверка в цикле, каждый раз по запросу "SELECT * FROM tblFileName WHERE FileName = Имя файла", очень накладно получается примерно 4.8 сек. (4758мс) Проверка с созданием и заполнением временной таблицы и запросом типа такого "select * from `temp` where FileName not in (select FileName from `tblFileName`)", достаточно быстро - 0.4 сек (437мс) Ваш способ - примерно 2.2 сек. (2168мс) Важно заметить, что во втором случае, время замерялось на две задачи, заполнение временной таблицы и сравнение, посредством одного запроса в бд. В первом же случае, данные сразу сравнивались, т.е. замерялся цикл запросов(3181 шт.) на выборку. Выбор очевиден Не знаю, что мне взбрело в голову в предыдущем сообщении...))) По поводу Limit, это ключевое слово позволяет не только ограничивать количество выбираемых данных, но и делать выборку блоками, например по 500 записей за раз (select FileName from `tblFileName` LIMIT 1,500), подошло бы, если бы нужно было извлекать блоками по 500 записей. вот такой запрос: FDQuery2.SQL.Clear; FDQuery2.SQL.Add('SELECT * FROM tblFileName'); FDQuery2.Active := True; FDQuery2.Open; if not FDQuery2.IsEmpty then begin FDQuery2.Last; mLogs.Lines.Add('Всего записей: ' + FDQuery2.RecordCount.ToString); mLogs.Lines.Add('ID последней записи: ' + FDQuery2.FieldByName('ID').AsString); end; FDQuery2.Close; Работает без проблем, извлекает сразу все записи. p.s. Тесты проходили на Windows 7 Pro.
  20. по поводу RecordCount уже миллион раз говорилось, что это количество сфетченных записей а не количество записей в датасете и никогда для перебора не используется цикл for dataset.open; while not dataset.eof do begin ... dataset.next; end; dataset.close; ручное сравнение записей с массивом данных тоже странный алгоритм для работы с SQL сервером все должно сводиться к подготовке данных для сервера и дальнейшей уже серверной работы, а не загрузки всей базы в память 512 Мб
  21. Я нашел решение, к сожалению, пока только для работы с UniDAC: Обновил UniDAC компоненты для Berlin до последней версии (6.3.12). Компоненты TUniConnection и TUniQuery отлично работают с SQLite в Android Service. FireDAC в Android Service пока запустить не удалось, но у меня такой задачи нет. В Deployment host приложения добавляю файл базы данных, Remote Path задаю ".\assets\internal\". И спокойно из сервиса получаю к нему доступ. Мой сервис локальный в одном потоке с приложением. Если делать Intent Service или Remote — наверное, придется помещать файл в другой, доступный каталог, или общаться через намерения (Intents). Надеюсь мой код будет полезен для вас. procedure TDM.conSQLiteBeforeConnect(Sender: TObject); begin {$IF DEFINED(iOS) or DEFINED(ANDROID)} conSQLite.Database := TPath.Combine(TPath.GetDocumentsPath, 'mybase.sqlite'); {$ENDIF} end; procedure TDM.conSQLiteError(Sender: TObject; E: EDAError; var Fail: Boolean); begin Log('--- DB error: %s:', [E.Message]); Fail := False; end; function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer; begin Log('+ START with Intent: ' + JStringToString(Intent.getAction.toString), []); if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) then begin try conSQLite.Disconnect; Log('- DB disconnected', []); except on E: Exception do Log('- can not to disconnect DB', [E.Message]); end; Log('... service to be stoped', []); JavaService.stopSelf; Result := TJService.JavaClass.START_NOT_STICKY; // don't reload service end else begin Log('... service started', []); try conSQLite.Connect; Log('+ DB connected', []); UniQuery.SQL.Text := 'select count(*) as ALLREC from orders'; UniQuery.Open; if UniQuery.RecordCount > 0 then begin UniQuery.First; Log('... record count: %s', [UniQuery.FieldByName('ALLREC').AsString]); end; UniQuery.Close; except on E: Exception do Log('- can not to connect DB: %s', [E.Message]); end; Result := TJService.JavaClass.START_STICKY; // rerun service if it stops end; end;
  22. для того чтобы узнать сколько записей в таблице, есть функция RecordCount. Возвращает целое число. зная количество сразу и стройте StrGrd
  23. Друзья, помогите, пож-та! Как можно подсчитать число записей после формирования выборки с использованием TFDQuery? RecordCount выдает значение 50 (RowsetSize по-умолчанию). Поделитесь, пож-та, примером кода и советом: как RowsetSize менять динамически исходя из объема выборки? Спасибо!
  24. procedure TFPreOrder.ListViewFill(LV: TListView; FDSource: TFDQuery; TextField, DetailField, TagField: string; IsClear: boolean); var i, index: integer; item: TListViewitem; begin if LV.Selected <> nil then index:= LV.Selected.Index else index:= -1; if FDSource.IsEmpty then begin // ShowMessage('Нет данных!'); LV.Items.Clear; exit; end; if IsClear then LV.Items.Clear; try LV.BeginUpdate; for i:= 1 to FDSource.RecordCount do begin FDSource.RecNo:= i; item:= LV.Items.Add; item.Text:= FDSource.FieldByName(TextField).AsString; item.Detail:= FDSource.FieldByName(DetailField).AsString; item.Tag:= FDSource.FieldByName(TagField).AsInteger; end; finally LV.EndUpdate; end; if index = -1 then exit; if LV.Items.Count >= index then LV.ItemIndex:= index; end; я обычно так заполняю... ну TFDQuery на TFDMemTable только сменить зы. ну и заполнение ListViewFill(ListView1, tbPreOrder, 'Name', 'Qty', 'GoodId', True);
  25. Нет, не вызывал. Прочитал в хелпе про FetchOptions, выставил FetchOptions.Manual = fmAll и теперь всё работает как надо. Только не пойму смысла. Если эта опция отвечает якобы за ограничение получения записей, то почему по факту в TFDQuery количество записей было больше выставленного максимума, т.е. все записи, которые возвращает мне запрос? По идее в данном случае в память DataSet не должно было грузиться более 50 записей. А так получается смысла в этой опции нет, она только не даёт свойству RecordCount стать выше установленного максимума, а в DataSet всё равно грузятся все записи, возвращённые запросом, и пройтись по ним можно вызывая в цикле Next() пока свойство Eof не будет истинным.
×
×
  • Создать...