Controlando o acesso
No final do artigo, o autor menciona criar um campo na tabela ACESSO contendo a descrição do objeto, porque é possível que um objeto com o nome de "btnIncluir" possa estar presente em vários formulários. Aí vem a dúvida, preciso criar mais campos, por exemplo, para os demais botões: btnExcluir, btnAlterar, btnPesquisar?
Menciona também criar um formulário onde o usuário possa dar a manutenção nas permissões (tabela ACESSO), ou seja, permitir ou não que determinado perfil tenha acesso a um determinado campo, etc.
Como poderia ser esse formulário?
Frederico Brigatte***
Respostas
Frederico Brigatte***
08/05/2013
Frederico Brigatte***
08/05/2013
USR_ID
USR_LOGIN
USR_NOME
USR_SENHA
ACS_PERFIL
Tabela ACESSO:
ACS_ID
ACS_GRUPO
ACS_SUBGRUPO
ACS_PERFIL
ACS_ENABLED
ACS_VISIBLE
Na tabela ACESSO o autor menciona sobre os botões, como INCLUIR, ALTERAR, EXCLUIR, CONSULTA. Criar 4 campos referentes aos botões: btnIncluir, btnAlterar, btnExcluir, btnConsulta?
Para que serve os campos ACS_GRUPO e ACS_SUBGRUPO?
Wilton Júnior
08/05/2013
tipo arquivo (menu ou grupo) e depois novo (submenu ou subgrupo) :P
Frederico Brigatte***
08/05/2013
Frederico Brigatte***
08/05/2013
O campo ACS_GRUPO serve para armazenar o nome do formulário.
O campo ACS_SUBGRUPO serve para armazenar o nome do objeto que está associado ao formulário.
O campo ACS_ENABLED trabalha armazenando a possibilidade do usuário ter este objeto habilitado (valor "S") ou não (valor "N")
No campo ACS_GRUPO gravo o nome do formulário, exemplo: frmCadastro_Clientes. No campo ACS_SUBGRUPO, gravaria os botões que quero controlar, exemplo: btnIncluir, btnAlterar, btnExcluir e btnConsultar.
Uma dúvida, onde na procedure ArmazenaAcesso saberia em qual formulário estou? Onde é gravado o nome do form na tabela?
Alisson Santos
08/05/2013
Frederico Brigatte***
08/05/2013
ACS_ID
ACS_GRUPO
ACS_SUBGRUPO
ACS_PERFIL
ACS_ENABLED
ACS_VISIBLE
Poderia haver uma outra tabela apenas para o perfil. Exemplo:
Tabela PERFIL
PFL_ID
PFL_PERFIL
A Tabela ACESSO, ficaria assim:
ACS_ID
ACS_GRUPO
ACS_SUBGRUPO
PFL_ID
ACS_ENABLED
ACS_VISIBLE
Correto isso?
Wilton Júnior
08/05/2013
grupo é frmprincipal.pas?
subgrupo TForm
isso?
Frederico Brigatte***
08/05/2013
Frederico Brigatte***
08/05/2013
Estou tentando montar as tabelas. Não entendi direito a parte do Grupo, SubGrupo. O autor menciona adicionar um campo na tabela ACESSO contendo a descrição do objeto, porque é possível que um objeto com o nome de "btnIncluir" possa estar presente em vários formulários.
Mas esses dois campos GRUPO e SUBGRUPO já não fazem isso, como diz:
O campo ACS_GRUPO serve para armazenar o nome do formulário, assim como o campo ACS_SUBGRUPO serve para armazenar o nome do objeto que está associado ao formulário.
Joel Rodrigues
08/05/2013
Ou seja, o grupo é utilizado para filtrar os controles de acesso de cada formulário, enquanto o subgrupo é para acessar cada componente do form para habilita-lo ou desabilita-lo.
Frederico Brigatte***
08/05/2013
Joel Rodrigues
08/05/2013
Frederico Brigatte***
08/05/2013
USUARIOS:
Usuario_Id Auto
Usuario_Nome Texto
Usuario_Login Texto
Usuario_Senha Texto
Perfil_Id Número
PERFIL:
Perfil_Id Auto
Perfil_Descricao Texto
ACESSO:
Acesso_ID Auto
Acesso_Grupo Texto
Acesso_SubGrupo Texto
Perfil_Id Integer
Acesso_Enabled Texto
Acesso_Visible Texto
Estou seguindo o artigo. Criei mais uma tabela Perfil e liguei os campos. Até aí está bom?
Joel Rodrigues
08/05/2013
Frederico Brigatte***
08/05/2013
Frederico Brigatte***
08/05/2013
Seria no evento OnCreate do frmACESSO? A chamada seria assim: ArmazenaAcesso(frmCadClientes). No caso se tiver mais formulários, iria adicionar no OnCreate:
ArmazenaAcesso(frmCadClientes);
ArmazenaAcesso(frmCad...)
ArmazenaAcesso(frmCad...)
E assim para todos os forms de Cadastro que teria no sistema?
Joel Rodrigues
08/05/2013
Frederico Brigatte***
08/05/2013
Application.CreateForm(Tfrm<NomeForm>, frm<NomeForm>);
ArmazenaAcesso(frm<NomeForm>);
Fazer isso antes de cada chamada? Assim?
Joel Rodrigues
08/05/2013
Outra forma seria:
Frm<nome> := TFrm<nome>Creat(Application);
Mas dá no mesmo.
Frederico Brigatte***
08/05/2013
DM.Acesso.Edit;
DM.Acesso.FieldByName('Acesso_Enabled').AsBoolean := not DM.Acesso.FieldByName('Acesso_Enabled').AsBoolean;
DM.Acesso.Post;
Frederico Brigatte***
08/05/2013
Application.CreateForm(TfrmCadastro_Clientes, frmCadastro_Clientes);
ArmazenaAcesso(frmCadastro_Clientes);
Frederico Brigatte***
08/05/2013
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
Tbl.TableType := ttParadox;
Tbl.TableName := 'ACESSO';
Frederico Brigatte***
08/05/2013
procedure TfrmAcessos.ArmazenaAcesso(Frm: TForm);
type
Vetor12 = array[0..11] of String;
var
Tbl : TTable;
Cmp,
Ctr : Integer;
Const
CTRL: Vetor12 = ('TButton', 'TBitBtn', 'TEdit', 'TMaskEdit', 'TMemo',
'TSpeedButton', 'TComboBox', 'TCheckBox', 'TListBox',
'TRadioButton', 'TSpinEdit', 'TMenuItem');
begin
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
Tbl.TableType := ttParadox;
Tbl.TableName := 'ACESSO';
try
Tbl.Open;
with Form1 do
for Cmp := 0 to ComponentCount - 1 do
for Ctr := 0 to High(CTRL) do
if UpperCase(Components[Cmp].ClassName) = UpperCase(CTRL[Ctr]) then
begin
Tbl.Append;
Tbl.FieldByName('ACS_GRUPO').AsString := Name;
Tbl.FieldByName('ACS_SUBGRUPO').AsString := Components[Cmp].Name;
Tbl.FieldByName('ACS_PERFIL').AsString := 'GERENTE';
Tbl.FieldByName('ACS_ENABLED').AsString := 'S';
Tbl.FieldByName('ACS_VISIBLE').AsString := 'S';
Tbl.Post;
Tbl.Append;
Tbl.FieldByName('ACS_GRUPO').AsString := Name;
Tbl.FieldByName('ACS_SUBGRUPO').AsString := Components[Cmp].Name;
Tbl.FieldByName('ACS_PERFIL').AsString := 'VENDEDOR';
Tbl.FieldByName('ACS_ENABLED').AsString := 'S';
Tbl.FieldByName('ACS_VISIBLE').AsString := 'S';
Tbl.Post;
Break;
end;
finally
Tbl.Close;
Tbl.Free;
end;
end;
Joel Rodrigues
08/05/2013
Aconselho, para este caso, criar e configurar a ADOConnection em um DataModuloe e apenas apontar a ADOTable ou ADOQuery para essa ADOConnection.
Frederico Brigatte***
08/05/2013
Frederico Brigatte***
08/05/2013
Frederico Brigatte***
08/05/2013
Joel Rodrigues
08/05/2013
Frederico Brigatte***
08/05/2013
procedure TfrmAcessos.ArmazenaAcesso(Frm: TForm);
Como ficaria essa parte já que estão no DM?
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
Tbl.TableType := ttParadox;
Tbl.TableName := 'ACESSO';
Frederico Brigatte***
08/05/2013
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
Tbl.TableType := ttParadox;
Tbl.TableName := 'ACESSO';
Joel Rodrigues
08/05/2013
2º) Se a tabela e a conexão já estão no DataModule, você não precisa usar esse trecho de código que, se você observar, verá que está criando a tabela e a configurando.
Frederico Brigatte***
08/05/2013
procedure TfrmAcessos.ArmazenaAcesso(Frm: TForm);
O que preciso fazer?
No caso do DM, não faço nada nesse código?
Frederico Brigatte***
08/05/2013
Joel Rodrigues
08/05/2013
Quando você pressiona CTRL+SHIFT+C com o cursor em cima da assinatura do método, o Delphi cria o corpo do método pra você. Nisso ele já põe o "TfrmAcessos." antes do nome do método (de acordo com o form, nesse caso, TFrmACesso).
Para você copiar para o DataModule, a primeira coisa é declarar o método. Depois implementá-lo usando o atalho que citei e então copiando apenas o corpo do método (entre o begin e o end).
Esta é a única forma de fazer? Não. Mas é a mais segura para você que não tem experiência ainda com isso, pois já faz da forma correta e vai aprendendo ao mesmo tempo.
Para mais informações, pesquise sobre como criar métodos no Delphi.
Frederico Brigatte***
08/05/2013
Joel Rodrigues
08/05/2013
Frederico Brigatte***
08/05/2013
procedure TfrmAcessos.ArmazenaAcesso(Frm: TForm);
Mas antes de public ou private, esta junto com as procedures da unit.
Frederico Brigatte***
08/05/2013
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
Tbl.TableType := ttParadox;
Tbl.TableName := 'ACESSO';
Estou usando ADO e é Access e está no DM.
Joel Rodrigues
08/05/2013
Não se declara métodos com o nome do form (TfrmAcessos). Esse nome é colocado NA IMPLEMENTAÇÃO do método apenas.
Frederico Brigatte***
08/05/2013
procedure ArmazenaAcesso(Frm: TForm);
Ai coloco ou na public ou private, certo?
Frederico Brigatte***
08/05/2013
Frederico Brigatte***
08/05/2013
Frederico Brigatte***
08/05/2013
type
TfrmAcessos = class(TForm)
StatusBar1: TStatusBar;
btGravar: TBitBtn;
btCancelar: TBitBtn;
sbLibera: TSpeedButton;
sbBloqueia: TSpeedButton;
GridGeral: TDBGrid;
Perfis: TDBLookupComboBox;
qryPerfil: TADOQuery;
dsQryPerfil: TDataSource;
Label1: TLabel;
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormShow(Sender: TObject);
procedure btCancelarClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ArmazenaAcesso(Frm: TForm);
end;
Joel Rodrigues
08/05/2013
Tente, veja se dá certo. Pesquise.
Não é que eu não queira responder, mas acho que você perde muito tempo perguntando "é assim?", "posso fazer?", "tô certo?". Tente, se der errado, aí você busca a solução do erro.
Boa sorte.
Frederico Brigatte***
08/05/2013
Aqui não faço nada? Estou usando ADO e Access:
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
Tbl.TableType := ttParadox;
Tbl.TableName := 'ACESSO';
Frederico Brigatte***
08/05/2013
CTRL: Vetor12 = ('TButton', 'TBitBtn', 'TEdit', 'TMaskEdit', 'TMemo',
'TSpeedButton', 'TComboBox', 'TCheckBox', 'TListBox',
'TRadioButton', 'TSpinEdit', 'TMenuItem');
Nessa linha acima, tiraria os que não fosse utilizar, somente isso pra mexer?
Aqui não faço nada? Estou usando ADO e Access:
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
Tbl.TableType := ttParadox;
Tbl.TableName := 'ACESSO';
Frederico Brigatte***
08/05/2013
Frederico Brigatte***
08/05/2013
CTRL: Vetor12 = ('TButton', 'TBitBtn', 'TEdit', 'TMaskEdit', 'TMemo',
'TSpeedButton', 'TComboBox', 'TCheckBox', 'TListBox',
'TRadioButton', 'TSpinEdit', 'TMenuItem');
Nessa linha acima, tiraria os que não fosse utilizar, somente isso pra mexer?
Aqui não faço nada? Estou usando ADO e Access:
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
Tbl.TableType := ttParadox;
Tbl.TableName := 'ACESSO';
Joel Rodrigues
08/05/2013
Tbl := TTable.Create(nil); Tbl.DatabaseName := ExtractFileDir(ParamStr(0)); Tbl.TableType := ttParadox; Tbl.TableName := 'ACESSO';
É fundamental que você saiba o que cada trecho do código faz, para saber quando e por quê utiliza-lo.
Frederico Brigatte***
08/05/2013
Tbl := TTable.Create(nil); -> Cria o objeto table
Tbl.DatabaseName := ExtractFileDir(ParamStr(0)); -> Pega o caminho do banco pelo no do executável
Tbl.TableType := ttParadox; -> Tipo da tabela, Paradox.
Tbl.TableName := 'ACESSO'; -> Nome da tabela utilizada, ACESSO.
Joel Rodrigues
08/05/2013
SE fosse fazer com ADO, sera algo do tipo:
tabela := TADOTable.Create(Self); tabela.Connection := conexao; tabela.TableName := 'ACESSO';
Joel Rodrigues
08/05/2013
SE fosse fazer com ADO, SERIA algo do tipo:
tabela := TADOTable.Create(Self); tabela.Connection := conexao; tabela.TableName := 'ACESSO';
Mas lembre-se: se os objetos já existem no DataModule, se você criou em design, não precisa criar em runtime.
Frederico Brigatte***
08/05/2013
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
Tbl.TableType := ttParadox;
Tbl.TableName := 'ACESSO';
Para isso:
tabela := TADOTable.Create(Self);
tabela.Connection := conexao;
tabela.TableName := 'ACESSO';
Uma Observação. Onde colocaria o procedimento ArmazenaAcesso? Seria assim que postou se o procedimento estivesse no DM. Em qual evento do DM colocaria?
Joel Rodrigues
08/05/2013
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
Tbl.TableType := ttParadox;
Tbl.TableName := 'ACESSO';
Para isso:
tabela := TADOTable.Create(Self);
tabela.Connection := conexao;
tabela.TableName := 'ACESSO';
SE VOCÊ JÁ TEM O ADOTable e o ADOConnection no DataModule, conforme você falou, você NÃO PRECISA cria-los em tempo de execução.
SE VOCÊ vai criar em tempo de execução, aí sim, o código é esse que falei.
Joel Rodrigues
08/05/2013
Eu já falei várias vezes que esse procedimento pode ficar em qualquer canto. Tanto no DataModule quanto no form de cadastro de acessos.
Com relação a onde você vai chama-lo, provavelmente deve ter um botão em algum lugar, do tipo "Cadastrar acessos" ou "Armazenar acessos".
Frederico Brigatte***
08/05/2013
Declaro: ou na private ou na public da unit do DM.
private
{ Private declarations }
public
{ Public declarations }
procedure ArmazenaAcesso(Frm: TForm);
var
DM: TDM;
implementation
{$R *.dfm}
procedure TDM.ArmazenaAcesso(Frm: TForm);//ou//procedure ArmazenaAcesso(Frm: TForm);//creio que seja essa,com certeza
begin
end;
Uma coisa ta martelando:
Eu já tenho o ADOTable e o ADOConnection no DataModule. Então não precisa usar esse código?
tabela := TADOTable.Create(Self);
tabela.Connection := conexao;
tabela.TableName := 'ACESSO';
Não quero criar em execução. Vou deixar o procedimento no DataModule. O que quero saber é se tenho que trocar onde está com asterisco.
Isso:
Tbl := TTable.Create(nil);
Tbl.DatabaseName := ExtractFileDir(ParamStr(0));
****Tbl.TableType := ttParadox; // aqui indica que é PARADOX
Tbl.TableName := 'ACESSO';
Para:
tabela := TADOTable.Create(Self); // essa linha caso não queira criar em execução, tiraria do código
****tabela.Connection := conexao; // aqui estou usando ACCESS
tabela.TableName := 'ACESSO';
Acho que não estava sendo claro na dúvida.
Joel Rodrigues
08/05/2013
Aqui você descarta, pois na ADOTable não é necessário definir o tipo de tabela.
Não importa qual banco está usando. Se a ADOConnection já está configurada, basta associa-la à ADOTable, desta forma como está.
Frederico Brigatte***
08/05/2013
Joel Rodrigues
08/05/2013
Você pode apenas criar o form e colocar alguns controles nele, apenas para teste.
Frederico Brigatte***
08/05/2013