2014-11-19 2 views
0

Я создал список и использовал его для добавления и удаления/загрузки и сохранения элементов в файл, который хорошо и хорошо. Однако, когда я пытаюсь использовать список на другом устройстве, я получаю сообщение об ошибке: необъявленный идентификатор.Необъявленный идентификатор с использованием списков

Первый блок ниже MainUnit - это то, где я пытаюсь использовать список и получать необработанный идентификатор ошибки. Ниже MainUnit находится ManageUsersUnit, это единица, в которой используется и создается список. Весь код работает со списком на ManageusersUnit, но не на любом другом устройстве.

unit MainUnit; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, Menus, ExtCtrls; 

implementation 

uses AddTenantUnit, HomeUnit, MainMenuUnit; 

{$R *.dfm} 

{ the error im getting is in this procedure} 

procedure TMainForm.FormCreate(Sender: TObject);. 
begin          
    if fileExists('Newuser.dat') 
    then 
    begin 
     UserListBox.Items.LoadFromFile('Newuser.dat'); 
    end 
    {endif}; 
end; 

unit ManageUsersUnit; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, MainUnit, StdCtrls, Menus, ComCtrls; 

type 
    TManageUsersForm = class(TForm) 
    AddUserButton: TButton; 
    RemoveUserButton: TButton; 
    ChangeUsernameButton: TButton; 
    ChangePasswordButton: TButton; 
    HomeButton: TButton; 
    UserListBox: TListBox; 
    UsernameEdit: TEdit; 
    SaveButton: TButton; 
    PasswordEdit: TEdit; 
    SubText1Label: TLabel; 
    SubText2Label: TLabel; 
    PassListBox: TListBox; 
    Button1: TButton; 

    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    ManageUsersForm: TManageUsersForm; 

implementation 

uses PassWord, AddUserUnit, HomeUnit; 

{$R *.dfm} 

procedure TManageUsersForm.HomeButtonClick(Sender: TObject); 
begin 
    HomeForm.show; 
    ManageUsersForm.Close; 
end; 

//Add UserName 
procedure TManageUsersForm.AddUserButtonClick(Sender: TObject); 

var 
    i : integer; 
    Found : Boolean; 
    AddUser : string; 

begin 
    {ManageUsersForm.close; 
    AddUserForm.ShowModal; } 

    Found := false; 
    AddUser := UsernameEdit.Text; 

    i := 0; 
    while i < userlistbox.Items.Count do 
    begin 
     if (UpperCase(AddUser) = Uppercase(userlistbox.Items[i])) 
     then 
     Found := True; 
     inc(i); 
    end; 
    {endhwile}; 

    if Found = False then 
    begin 
     userlistbox.Items.Add(AddUser); 
     UsernameEdit.Text := ''; 
     showMessage(AddUser + ' added'); 
    end 
    else 
    showMessage(AddUser + ' is already present.'); 
    {endif}; 
end; 

procedure TManageUsersForm.RemoveUserButtonClick(Sender: TObject); 
var 
    deleted : string; 
begin 
    with UserListBox do 
    begin 
     if ItemIndex = -1 
     then 
     showMessage('You must select a User first.') 
     else 
     begin 
      Deleted := Items.Strings[ItemIndex]; 
      Items.Delete(ItemIndex); 
      showMessage(Deleted + ' deleted'); 
     end; 
     {endif}; 
    end; 
end; 

procedure TManageUsersForm.Button1Click(Sender: TObject); 
var 
    i : integer; 
    Found : Boolean; 
    check : string; 
begin 
    check := PasswordEdit.Text; 
    Found := false; 

    i := 0; 
    while i < userlistbox.Items.Count do 
    begin 
     if (UpperCase(check) = Uppercase(userlistbox.Items[i])) 
     then 
     Found := True; 
     inc(i); 
    end; 
    {endhwile}; 

    if Found = False 
    then 
    begin 
     showMessage(check + ' Incorrect Username'); 
    end 
    else 
    showMessage(' well done in file :).'); 
    {endif}; 
end; 

procedure TManageUsersForm.SaveButtonClick(Sender: TObject); 
begin 
    assignfile (userFile,'Newuser.dat'); 
    UserListbox.Items.SaveToFile('Newuser.dat'); 
    showMessage('Saved to file'); 
end; 

procedure TManageUsersForm.FormCreate(Sender: TObject); 
begin 
    if fileExists('Newuser.dat') 
    then 
    begin 
     UserListBox.Items.LoadFromFile('Newuser.dat'); 
    end 
    {endif}; 
end; 

procedure TManageUsersForm.TestBtnClick(Sender: TObject); 
begin 
    AddUserForm.ShowModal; 
end; 

end. 
+0

Похоже, вы знаете * используя * единиц. Почему бы вам не использовать «ManageUsersUnit»? 'ManageUsersUnit.ManageUsersForm.UserListBox.Items.LoadFromFile ('..' –

+1

Окно списка находится внутри класса. Должны ли вы действительно подталкивать его из другого класса в другом блоке? К сожалению, для вас Delphi заставляет вас использовать эти глобальные переменные и сделать объекты пользовательского интерфейса видимыми повсюду. –

ответ

4

Ваши MainUnit потребности использовать ManageUsersUnit блок. Если единственные ссылки на форму в этом другом блоке находятся в разделе implementation, добавьте его в пункт uses. Как правило, вы должны только добавлять к интерфейсу использование предложения, если это абсолютно необходимо.

unit MainUnit; 

/// ... 

implementation 

    uses AddTenantUnit, HomeUnit, MainMenuUnit, ManageUsersUnit; 

Ваш код затем ссылается на UserListBox непосредственно, но эта ссылка является переменной членом TManageUsersForm класса, так что вы должны сначала определить экземпляр этого класса, прежде чем получить доступ к членам этого экземпляра.

В этом случае, как представляется, публичный экземпляр уже доступны, которые вы предположительно собираетесь использовать: ManageUsersForm

Так что ваш код для загрузки файлов данных в списке должны быть:

ManageUsersForm.UserListBox.Items.LoadFromFile('Newuser.dat'); 

Этот исправит вашу немедленную проблему. Однако с этим подходом есть много неправильного.

  1. MainUnit предполагает, что ManageUsersForm является действительным, существующая форма экземпляра. Если для формы установлено значение AutoCreate в проекте, тогда это может быть действительно, но опасно, так как делает ваш код уязвимым для изменения способа создания ваших форм.

  2. MainUnit является неподобающим ответственность за некоторые из поведения ManageUsers формы. Если форма ManageUsers действительно управляет пользователями, это должно включать постоянство пользователей в самих файлах.

  3. MainUnit сильно зависит от внутренних деталей ManageUsers формы. Мы говорим, что он «тесно связан». Если форма ManageUsers модифицирована, чтобы использовать, например, сетку для представления списка пользователей, код MainUnit будет разорван, поскольку он полагается на тесное знание о том, что список пользователей является специально списком.

В результате так, что VCL работает, элементы управления пользовательского интерфейса на форме в Delphi являются общедоступными, но вы должны рассматривать их как частного (или, в лучшем случае, защищен) , Ваша форма ManageUsers должна предоставлять публичный интерфейс функциональности, которую он предоставляет «внешнему миру», который имеет дело с терминами пользователя данных.

Не должно быть ссылок на элементы пользовательского интерфейса формы - включая любые обработчики событий - вне самой формы (или классов формы потомков, если вы используете иерархию OO классов форм).

+0

+ один Хорошо сделано для перехода на лишнюю милю –

Смежные вопросы