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

krapotkin

Пользователи
  • Постов

    2 180
  • Зарегистрирован

  • Посещение

  • Победитель дней

    209

Сообщения, опубликованные krapotkin

  1. вот программа выключилась. что стало с деревом? рассосалось?

    дерево  - тем более нужен класс, хранящий ссылку на детей, скорее всего того же класса TYourClassList

    все же просто как мычание. умножаете количество элементов на 8 байт, получаете примерный размер массива указателей на объекты
    плюс к этому прикидываете размер самих объектов, и получаете количество памяти для хранения вашей структуры. ООООчень грубо, но пойдет..

  2. тогда, думаю, вам нужно просто хранить все это богатство в какой-то (локальной?) БД

    смысла держать это все в памяти вы никакого не обозначили.

    если нужно что-то найти, достать, обычная схема работы с моделью данных, сам список моделей обычно хранится в TYourClassList = TObjectList<TYourClass>

    при необходимости загружаем туда, работаем, выгружаем оттуда

    при этом выгрузка/загрузка становится независимой от хранения - хоть из интернета скачивайте

  3. а есть какие-то подробности? для чего этот список? и что значит "большой" ? 10 тыс и 10 млн оба немаленькие, но есть нюанс

    опять же, есть ли необходимость искать элементы в нем? или нужно ли чтобы они были упорядочены?

    это все важно

    есть также сомнение, что действительно нужен одномоментно в памяти *действительно* большой кусок данных

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

    и потом что нажать, чтобы получить ошибку.

    еще раз обращаю внимание, что для того, чтобы вам помогали, нужно как-то позаботиться о том, кто должен почему-то разбираться в вашем коде. Он не отформатирован даже. Есть волшебство 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;

     

    QIP Shot - Screen 059.png

  5. все очень просто.
    представьте что у вас 100500 тысяч пользователей, и давайте всех их скачаем на компьютер, а тут поищем среди них через Locate()

    сама по себе плохая мысль.

    но кроме того, это значит, что вам еще и все их пароли должны прислать из базы? т.е. вам останется только выбрать, на чье имя вам интереснее оформить вашу ипотеку?

  6. форма нужна для отображения визуальных компонентов

    подключение и датасеты вообще ни разу не визуальные

    кроме того если датасеты еще можно положить на каждую форму/фрейм отдельно, то подключение лучше держать одно. Какой смысл для этого держать форму, там же нет взаимодействия с пользователем ??

    Не очень важное, но...
    Главной формой приложения становится первая созданная форма. А вот модуль данных можно создавать до форм. И подключение проводить тоже до. Если этого требует логика приложения.

     

  7. Тезисно. Прямое подключение разрушается, когда соединение разрывается. А в мобильной сети оно постоянно может отключаться и включаться, переключаться между WiFi и 4G. Установление подключения к БД тогда требуется каждый раз, как происходит такой разрыв. У HTTP запрос проходит разово. Запросили - ответил, или нет. Соединение не требуется. Не прошел запрос, ничего, повторим.

  8. начнем с важных вещей:

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

    у вас тут - сначала подключаемся, потом заполняем свойства. Кому они там нужны уже?

              FDConnection1.Connected := true;
              FDConnection1.Params.Pooled := false;
              FDConnection1.LoginPrompt := false;
              FDConnection1.Params.DriverID := 'MSAcc';....
    то же и с запросом. Сначала сделать запрос с пустым текстом, а текст запроса пообещать позже дослать?

              FDQuery1.Active := true;
              FDQuery1.SQL.Add('SELECT * FROM usersbase');

    логично, что сервер говорит SQL_NO_DATA. запроса-то нет.

    кроме того, если несколько раз нажать, то каждый раз к запросу будет добавляться строка SQL.Add(...)? зачем?

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

              FDQuery1.SQL.Text := 'SELECT * FROM usersbase';
              FDQuery1.Active := true;

    Во всех этих ошибках нет никакой специфики FireDac. Для ADO все идентично прям на 102%

    еще по мелочам

    -ConnectionString это совсем не Database Name. Нужно читать доки. Примечание про ADO в силе. Там точно так же.

    -это конечно волшебное решение в процедуру подключения передавать параметром TLabel. Нафига ??

    -сама форма с компонентами доступа тоже не нужна. Нужен модуль данных.

    -ну и наименования форм конечно.
    Можно говорить о том, что проект исключительно мой и как хочу, так и делаю, тогда вопрос - а почему тогда он тут? И почему я должен пробираться сквозь мысли автора чтобы решить его проблему? 

    - последнее, ваш архив весит 30+ МБайт. Мой - 25 КБайт. Для чего мне все эти остальные файлы?

    CagortaModified.7z

  9. нет, неверно

    в ListView1ItemClick вам передается параметр AItem - это и есть тот item по которому мы кликнули

    if FClickedButton = Base then
    begin
      FirstValue := AItem.Index; 
    end
    else
    begin
     SecondValue := AItem.Index; 
    end;
    UpdateValueLabels();


    если смотреть в UpdateValueLabels - какое отношение имеет ListView1.Selected к выводу переменных в кнопки ?

    из вашего кода следует, что вы сделали FirstValue, SecondValue : integer;
    логично предположить, что значение -1 будет показывать, что кнопка пуста

    procedure TForm1.UpdateValueLabels();
    begin
      if FirstValue = -1 then
        Base.text := ListView1.items[FirstValue].text
      else
        Base.text := '';
    
      if SecondtValue = -1 then
        Hypo.text := ListView1.items[SecondValue].text
      else
        Hypo.text := '';
    end;
  10. это методы, которые нужно написать

    я старался, чтобы по названиям было понятно, что они должны делать

    если смотреть на вашу картинку, то очевидно, что список показывается только тогда, когда мы нажали на кнопку, этим должен заняться метод ShowSelectionList()

    после выбора, скорее всего, нужно будет убрать с экрана этот список, т.е. нужен еще один метод типа HideSelectionList().

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

     

    UpdateValueLabels() как следует из названия - отражает то, что у нас хранится в переменных FirstValue и SecondValue, в соответствующие места на экране, в первую и вторую метку

  11. ну так совсем другое дело )) сразу бы так

    создаем поля формы FirstValue, SecondValue :  TSomeType; например запись Name:string, ID:integer;
    FClickedButton : TObject; обеим кнопкам даем один и тот же обработчик

    procedure TForm1.ButtonClick(Sender : TObject);
    begin
      FClickedButton  := sender;
      ShowSelectionList();
    end;
    
    

    при клике на ListView

    if FClickedButton = button1 then
    begin
       FirstValue := значение из списка...
    end
    else
    begin
       SecondValue := значение из списка...
    end;
    UpdateValueLabels();

     

  12. записывает ссылку на себя в эту переменную.

     

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

    еще:

    как-то так сложилась практика, что владельцем создаваемых компонентов является форма или фрейм, а не Application. это логично, потому что компоненты уничтожаются вместе с формой, на которой размещены. Именно за это отвечает параметр Owner.

  13. думаю, что более правильно один из двух вариантов

    1) вообще не создавать переменную. в onClose просто делать Free

    2) созданной форме вешать на OnClose обработчик и там делать проверку ModalResult , так же как реализовано в TDialogService.MessageDialog

     

  14. Это называется UX - сценарий использования пользователем вашей программы.
    Собственно, сначала придумывается из головы UX, а только потом пишется программа. Так что это к вам вопрос - что делать с уже введенными данными

    С точки зрения программирования нужно всего лишь
     

    SelectedList.Clear();
    UpdateLabels();

     

  15. я не знаю, откуда вы берете текст, который размещается в ListView но он же должен где-то храниться
    вот оттуда его берём в методе UpdateLabels
     

    TForm3 = class(TForm)
    ...
    SelectedList : TList<integer>;
    ...
    end;
    
    ........
    
    procedure TForm3.FormCreate(Sender : TObject);
    begin
      SelectedList := TList<integer>.Create;
    end;
    
    procedure TForm3.FormDestroy(Sender : TObject);
    begin
      FreeAndNil(SelectedList);
    end;
    
    procedure TForm3.ListView1ItemClick(const Sender: TObject; const AItem: TListViewItem);
    begin
      if SelectedList.Count = 2 then exit;
      case Selected Count of
        0 : begin
          SelectedList.Add(AItem.Index);
          UpdateLabels();
        end;
        1 : begin
          if SelectedList[0] <> AItem.Index then
            SelectedList.Add(AItem.Index);
          UpdateLabels();
        end;
      end;
    end;
    
    procedure TForm3.UpdateLabels();
    begin
      if SelectedList.Count > 0 then
        label1.text := varIDontKnowWhereYourTextStored[ SelectedList[0] ]
      else 
        label1.text := '';
    
      if SelectedList.Count > 1 then
        label2.text := varIDontKnowWhereYourTextStored[ SelectedList[1] ]
      else 
        label2.text := ''; 
    end;

     

×
×
  • Создать...