Histórico da Página
...
O cadastro de consulta rápida deve ser realizada realizado através do formulário FRM0015 - Indicadores. Neste cadastro é necessário preencher com as informações da consulta.
Nota |
---|
Para que seja possível a visualização da consulta rápida no Fluig, a mesma deve estar liberada, ou seja, o desenvolvimento da mesma deve ser encerrada ter sido encerrado através da ferramenta GOLD. |
...
O nome da consulta deve seguir o padrão composto pelo código do sistema Logix, a letra "i" e a sequencia de identificação do indicador.
Desenvolvimento
Após a criaçãoo cadastro da consulta rápida, deve ser desenvolvido o fonte 4GL com as funções padrões para a execução da consulta rápida mesma no Fluig. Atualmente são necessárias três 4 funções para cada indicador, sendo:
- START: função responsável por retornar dados iniciais da consulta rápida;
- SEARCH: função responsável para retornar os dados da consulta;
- GET_DATA: função semelhante a função SEARCH, preparada para receber e tratar filtro customizado do widget do Fluig;
- AUTO_COMPLETE: função responsável por retornar as informações do auto-completar do widget no Fluig.
Nota |
---|
Até o momento, não será possível efetuar a chamada do LOG de segurança padrão do LOGIX nas funções da consulta rápida. Estas consultas não são cadastradas no menu e não são dadas permissões no ERP, apenas via Fluig Identity. Por este motivo se as funções possuírem chamadas do LOG de segurança, a execução da consulta será interrompida. |
...
- os filtros que poderão ser realizados;
- as colunas que irão compor comporão a grade com os dados da consulta;
- a lista de filtros pré-definidos que poderão ser utilizados; e
- a lista com o nome dos programas que poderão ser executados a partir da consulta.
...
A execução da função acima irá permitir possibilitará a inicialização do widget de consulta rápida e irá criá-lo semelhante a , o qual será criado de forma semelhante à tela abaixo:
Função de SEARCH
Informações |
---|
Quando for necessário utilizar filtro customizado, a função SEARCH pode ser omitida, sendo obrigatório implementar apenas a função GET-DATA. |
No 4GL o nome desta função deve ter o sufixo _indicator_search, deve ter e receberá como parâmetros:
- nome da coluna de filtro selecionada pelo usuário;
- valor do filtro informado pelo usuário;
- valor do filtro pré-definido selecionado;
- nome da coluna de ordenação;
- tipo de ordenação;
- quantidade de linhas por página; e
- número da página de consulta atual.
...
Bloco de código | ||||
---|---|---|---|---|
| ||||
#---------------------------------------------------------------------------------------------------------------# FUNCTION logi1_indicator_search(l_filter_column,l_filter_value,l_selection,l_sort_col,l_sort_order,l_rows,l_page) #---------------------------------------------------------------------------------------------------------------# DEFINE l_filter_column CHAR(50), #Coluna de filtro (opcional) l_filter_value CHAR(300), #Valor do filtro da coluna acima (opcional) l_selection CHAR(01), #Valor selecionado na lista de filtros (opcional) l_sort_col CHAR(50), #Coluna de ordenação (opcional) l_sort_order CHAR(04), #Tipo de ordenação ASC ou DESC (opcional) l_rows SMALLINT, #Máximo de registros por página l_page SMALLINT #Página atual de pesquisa DEFINE l_sql_stmt CHAR(500), l_sql_count CHAR(500), l_where_clause CHAR(250) DEFINE l_ind SMALLINT, l_position INTEGER DEFINE lr_search RECORD data ARRAY[60] OF RECORD #Lista com os resultados da consulta cod_usuario LIKE usuarios.cod_usuario, nom_funcionario LIKE usuarios.nom_funcionario, ind_admlog LIKE usuarios.ind_admlog END RECORD, count SMALLINT, #Total de registros que serão retornados total INTEGER, #Total de registros encontrados na consulta (sem a paginação) cpage INTEGER, #Página de registros atual pages SMALLINT #Total de páginas resultantes da consulta END RECORD INITIALIZE lr_search.* TO NULL #Verifica a coluna e o filtro informado por parâmetro IF l_filter_column IS NOT NULL AND l_filter_value IS NOT NULL THEN LET l_where_clause = "UPPER(g."||l_filter_column CLIPPED||") LIKE '%"||UPSHIFT(l_filter_value) CLIPPED||"%'" ELSE LET l_where_clause = "1=1" END IF #Adiciona o filtro conforme selecionado IF l_selection IS NOT NULL AND l_selection <> "*" THEN LET l_where_clause = l_where_clause CLIPPED," AND u.ind_admlog = '",l_selection CLIPPED,"'" END IF #Monta o SQL da consulta rápida LET l_sql_stmt = "SELECT DISTINCT", " u.cod_usuario,", " u.nom_funcionario,", " u.ind_admlog", " FROM usuarios u", " LEFT OUTER JOIN log_usu_grupos l", " ON l.usuario = u.cod_usuario", " LEFT OUTER JOIN log_grupos g", " ON g.grupo = l.grupo", " WHERE ",l_where_clause #Monta o SQL de COUNT (é necessário ser sem ORDER BY) LET l_sql_count = "SELECT COUNT(*) FROM ("||l_sql_stmt CLIPPED||") t" #Atribui o ORDER BY para o SQL da consulta rápida IF l_sort_col IS NOT NULL AND l_sort_order IS NOT NULL THEN LET l_sql_stmt = l_sql_stmt CLIPPED||" ORDER BY "||l_sort_col CLIPPED||" "||l_sort_order ELSE LET l_sql_stmt = l_sql_stmt CLIPPED||" ORDER BY 1" END IF WHENEVER ERROR CONTINUE PREPARE var_indicator_count FROM l_sql_count WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL QSFWQVLOGIX_consoleDebugMessage(l_sql_count) CALL log0030_processa_err_sql("PREPARE SQL","var_indicator_count",1) RETURN NULL END IF WHENEVER ERROR CONTINUE EXECUTE var_indicator_count INTO lr_search.total WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL log0030_processa_err_sql("EXECUTE SQL","var_indicator_count",1) FREE var_indicator_count RETURN NULL END IF #Conta a quantidade de página que resultou a consulta LET lr_search.pages = LOG_round(lr_search.total/l_rows,0) #Verifica se a página informada ultrapassou o total de páginas IF lr_search.pages > 0 THEN IF l_page > lr_search.pages THEN LET lr_search.cpage = lr_search.pages ELSE LET lr_search.cpage = l_page END IF ELSE LET lr_search.pages = 1 LET lr_search.cpage = l_page END IF WHENEVER ERROR CONTINUE FREE var_indicator_count PREPARE var_indicator_search FROM l_sql_stmt WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL QSFWQVLOGIX_consoleDebugMessage(l_sql_stmt) CALL log0030_processa_err_sql("PREPARE SQL","var_indicator_search",1) RETURN NULL END IF WHENEVER ERROR CONTINUE DECLARE cq_indicator_search CURSOR FOR var_indicator_search WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL log0030_processa_err_sql("DECLARE CURSOR","cq_indicator_search",1) FREE var_indicator_search RETURN NULL END IF WHENEVER ERROR CONTINUE OPEN cq_indicator_search WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL log0030_processa_err_sql("OPEN CURSOR","cq_indicator_search",1) FREE var_indicator_search RETURN NULL END IF #Calcula a posição do registro atual conforme a página e a quantidade de #linhas por página LET l_ind = 1 LET l_position = ((l_rows * l_page) - l_rows) + 1 WHILE TRUE WHENEVER ERROR CONTINUE FETCH ABSOLUTE l_position cq_indicator_search INTO lr_search.data[l_ind].* WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN IF sqlca.sqlcode <> NOTFOUND THEN CALL log0030_processa_err_sql("FETCH CURSOR","cq_indicator_search",1) END IF EXIT WHILE END IF LET l_ind = l_ind + 1 LET l_position = l_position + 1 #Não pode ultrapassar o limite de registros por página IF l_ind > l_rows THEN EXIT WHILE END IF END WHILE WHENEVER ERROR CONTINUE CLOSE cq_indicator_search FREE cq_indicator_search WHENEVER ERROR STOP LET lr_search.count = l_ind - 1 RETURN lr_search END FUNCTION |
...
Informações |
---|
A tecnica apresentada aqui foi pensada para reduzir ao máximo a necessidade de alteração dos programas já construidos em função , motivada pela inclusão de novos parâmetros. Por isso, é apresentada a passagem dos mesmos usando a função _ADVPL_QSSetParametersFWQVSetParametersLogix(), cuja chamada também é realizada pelo serviço REST , desenvolvido pelo Framework, e que é o responsável por chamar o programa de consulta rápida desenvolvido pela da área de negócio/segmento. |
Esta função é de definição opcional e deve ser criada quando houver necessidade de tratar filtros customizados do widget de consulta rápida. Ela será executada quando estiver presente no fonte 4GL e RPO e deve estar preparada para tratar o parâmetro customfilter quando este for informado na chamada REST proveniente do widget de consulta rápida.
No 4GL o nome da função deve conter o sufixo _indicator_get_data e não receberá parâmetros. Estes serão passados para a função através de uma área de memória compartilhada, acessível através da função _ADVPL_QSGetParameterFWQVGetParameterLogix("nome_do_parametro"), onde "nome_do_parâmetro" é o identificador do campo dentro da área de memória compartilhada que contem o valor desejado.
O Quando da criação dessa função, o corpo da função SEARCH deve ser transferido para a função GET-DATAela, sendo que a primeira deve ser mantida no 4GL, por questões de compatibilidade, e deve ser reescrita para apenas chamar a função GET-DATA passando os parâmetros através da área de memória compartilhada.
Transferindo dados para a função GET-DATA
Os dados devem Havendo necessidade, os parâmetros podem ser transferidos para a função GET-DATA usando uma variável do tipo RECORD, que deve ser definida exatamente como segue:
...
A variável RECORD deve ser preenchida com os valores correspondentes antes de ser passada como parâmetro para a função _ADVPL_QSSetParametersFWQVSetParametersLogix(<variavel_record>). Lembre-se de inicializar o a variável RECORD antes de atribuir valores ao mesmoaos campos da mesma.
Exemplo
Trecho demonstrando a função SEARCH reescrita para chamar a função GET-DATA, caso seja necessário manter as duas funções no fonte. Também é mostrada a definição da variável RECORD e a utilização da função _ADVPL_QSSetParametersFWQVSetParametersLogix().
Bloco de código | ||
---|---|---|
| ||
#---------------------------------------------------------------------------------------------------------------# FUNCTION log1i_indicator_search(l_filter_column,l_filter_value,l_selection,l_sort_col,l_sort_order,l_rows,l_page) #---------------------------------------------------------------------------------------------------------------# DEFINE l_filter_column CHAR(50), #Coluna de filtro (opcional) l_filter_value CHAR(300), #Valor do filtro da coluna acima (opcional) l_selection CHAR(01), #Valor selecionado na lista de filtros (opcional) l_sort_col CHAR(50), #Coluna de ordenação (opcional) l_sort_order CHAR(04), #Tipo de ordenação ASC ou DESC (opcional) l_rows SMALLINT, #Máximo de registros por página l_page SMALLINT #Página atual de pesquisa DEFINE lr_params RECORD l_searchcol CHAR(50), l_searchval CHAR(300), l_selection CHAR(01), l_sortcol CHAR(50), l_sortorder CHAR(04), l_rows CHAR(10), l_page CHAR(10), l_customfilter CHAR(500) END RECORD INITIALIZE lr_params.* TO NULL # O record recebe os parâmetros da função search LET lr_params.l_searchcol = l_filter_column LET lr_params.l_searchval = l_filter_value LET lr_params.l_selection = l_selection LET lr_params.l_sortcol = l_sort_col LET lr_params.l_sortorder = l_sort_order LET lr_params.l_rows = l_rows LET lr_params.l_page = l_page LET lr_params.l_customfilter = "" # Como customfilter não é recebido na função search, seu valor é vazio. CALL _ADVPL_QSSetParametersFWQVSetParametersLogix(lr_params) # Grava os parâmetros na área compartilhada RETURN LOG1ilogi1_indicator_get_data() # O retorno da função search é o mesmo da get_data END FUNCTION |
...
Os dados atribuidos à área de memória compartilhada são recuperados através da função _ADVPL_QSGetParameterFWQVGetParameterLogix("nome_do_parametro"), onde "nome_do_parametro" deve ser exatamente igual ao campo da variável RECORD que se deseja recuperar.
No exemplo abaixo, vemos o trecho
Exemplo
Trecho da função GET-DATA onde é feita a recuperação dos parâmetros.
Exemplo
Bloco de código | ||
---|---|---|
| ||
#---------------------------------------------------------------------------------------------------------------# FUNCTION log1i_indicator_get_data() #---------------------------------------------------------------------------------------------------------------# DEFINE l_filter_column CHAR(50), #Coluna de filtro (opcional) l_filter_value CHAR(300), #Valor do filtro da coluna acima (opcional) l_selection CHAR(01), #Valor selecionado na lista de filtros (opcional) l_sort_col CHAR(50), #Coluna de ordenação (opcional) l_sort_order CHAR(04), #Tipo de ordenação ASC ou DESC (opcional) l_rows SMALLINT, #Máximo de registros por página l_page SMALLINT, #Página atual de pesquisa l_customfilter CHAR(500) # ...Trecho de código omitido para maior clareza do exemplo... #Recupera os valores dos parametros LET l_filter_column = _ADVPL_QSGetParameterFWQVGetParameterLogix("l_searchcol") LET l_filter_value = _ADVPL_QSGetParameterFWQVGetParameterLogix("l_searchval") LET l_selection = _ADVPL_QSGetParameterFWQVGetParameterLogix("l_selection") LET l_sort_col = _ADVPL_QSGetParameterFWQVGetParameterLogix("l_sortcol") LET l_sort_order = _ADVPL_QSGetParameterFWQVGetParameterLogix("l_sortorder") LET l_rows = _ADVPL_QSGetParameterFWQVGetParameterLogix("l_rows") LET l_page = _ADVPL_QSGetParameterFWQVGetParameterLogix("l_page") LET l_customfilter = _ADVPL_QSGetParameterFWQVGetParameterLogix("l_customfilter") CALL conout( "Executando LOG1i_indicator_get_data..." ) CALL conout( "Coluna de filtro...: " || l_filter_column ) CALL conout( "Valor de filtro....: " || l_filter_value ) CALL conout( "Selecao............: " || l_selection ) CALL conout( "Coluna de Ordenacao: " || l_sort_col ) CALL conout( "Ordenacao:.........: " || l_sort_order ) CALL conout( "LInhas.............: " || l_rows ) CALL conout( "Pagina.............: " || l_page ) CALL conout( "Filtro customizado.: " || l_customfilter ) # A partir daqui, segue o restante da função get_data... |
...
O valor informado no parâmetro customfilter deve estar de acordo com a sintaxe SQL usada no 4GL . Ou seja, e sua aplicação na pesquisa não requer tratamento especifico. Caso Ou seja, caso o conteúdo do parâmetro customfilter não esteja correto, não será necessário qualquer tratamento de exceção adicionalé responsabilidade do programa de consulta rápida tratar os eventuais erros de execução relacionados.
Exemplo
Trecho do corpo da função GET-DATA mostrando como utilizar o valor recebido no parâmetro customfilter.
...
No 4GL o nome desta função deve ter o sufixo _indicator_autocomplete, deve ter como parâmetro:
- nome da coluna selecionado selecionada para filtro; e
- e o valor do filtro informado pelo usuário.
...
Bloco de código | ||||
---|---|---|---|---|
| ||||
#-------------------------------------------------------------------# FUNCTION logi1_indicator_autocomplete(l_filter_column,l_filter_value) #-------------------------------------------------------------------# DEFINE l_filter_column CHAR(50), #Coluna de filtro (opcional) l_filter_value CHAR(300) #Valor do filtro da coluna acima (opcional) DEFINE l_sql_stmt CHAR(500), l_sql_count CHAR(500), l_where_clause CHAR(250) DEFINE l_ind SMALLINT, l_position INTEGER DEFINE lr_autocomplete RECORD data ARRAY[500] OF CHAR(200), count SMALLINT END RECORD CHAR(250) DEFINE l_ind SMALLINT, l_position INTEGER DEFINE lr_autocomplete RECORD data ARRAY[500] OF CHAR(200), count SMALLINT END RECORD INITIALIZE lr_autocomplete.* TO NULL #Verifica a coluna e o filtro informado por parâmetro IF l_filter_column IS NOT NULL AND l_filter_value IS NOT NULL THEN LET l_where_clause = "UPPER(g."||l_filter_column CLIPPED||") LIKE '%"||UPSHIFT(l_filter_value) CLIPPED||"%'" ELSE LET l_where_clause = "1=1" END IF #Monta o SQL do auto-completar LET l_sql_stmt = "SELECT g.",l_filter_column CLIPPED, " FROM log_grupos g", " END IF #Monta o SQL do auto-completar LET l_sql_stmt = "SELECT g.",l_filter_column CLIPPED, " FROM log_grupos g", " WHERE ",l_where_clause CLIPPED, " ORDER BY 1" WHENEVER ERROR CONTINUE PREPARE var_indicator_autocomplete FROM l_sql_stmt WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL QSFWQVLOGIX_consoleDebugMessage(l_sql_stmt) CALL log0030_processa_err_sql("PREPARE SQL","var_indicator_autocomplete",1) 1) RETURN NULL END IF WHENEVER ERROR CONTINUE DECLARE cq_indicator_autocomplete CURSOR FOR var_indicator_autocomplete WHENEVER ERROR STOP IF sqlca.sqlcode <> 0 THEN CALL log0030_processa_err_sql("DECLARE CURSOR","cq_indicator_autocomplete",1) FREE var_indicator_autocomplete RETURN NULL END IF WHENEVER ERROR CONTINUE LET l_ind = 1 FOREACH cq_indicator_autocomplete INTO lr_autocomplete.data[l_ind] IF sqlca.sqlcode <> 0 THEN CALL log0030_processa_err_sql("FOREACH CURSOR","cq_indicator_autocomplete",1) ) EXIT FOREACH END IF LET l_ind = l_ind + 1 IF l_ind > 500 THEN EXIT FOREACH END IF END FOREACH FREE cq_indicator_autocomplete WHENEVER ERROR STOP LET lr_autocomplete.count = l_ind - 1 RETURN lr_autocomplete END FUNCTION |
Esta função é executada quando o usuário informa algum filtro na consulta, conforme mostra o exemplo abaixo:
...
Quando o usuário, no widget de consulta rápida, selecionar um registro na grade e clicar em uma das ações selecionadas é necessário que a execução do programa Logix selecionado já exiba o registro selecionado já consultado.
Para que isso possa ser realizado seja possível é necessário alterar os programas que são informados como ações na função de START. Deve-se incluir nestes programas uma verificação para obter os parâmetros de execução utilizando a função APPLICATION_getNumArgs e já efetuar a operação de consulta.
...
Quando executado através do widget de consulta rápida do Fluig, a função APPLICATION_getNumArgs sempre irá retornar no mínimo três parâmetros, sendo:
- ACTION: a palavra "INDICATOR" para identificar que trata-se da ação de um indicador;
- INDICATOR: o código do indicador cadastrado no FRM0015.
- A partir do
...
- terceiro parâmetro, são
...
- enviadas as colunas com os valores selecionados pelo usuário.