Histórico da Página
Índice |
---|
Composition Setup |
---|
import.css=/download/attachments/5263564/framework.css |
Objetivo
A consulta rápida é responsável por apresentar para o usuário dados de indicadores definidos pelas áreas de negócio para cada um dos ERPs TOTVS. A obtenção destas informações é feita através de serviços REST implementados por cada um dos segmentos. O widget de consulta rápida será semelhante ao da figura abaixo:
Cadastrando as consultas
O cadastro de consulta rápida deve ser realizado através do formulário FRM0015 - Indicadores. Neste cadastro é necessário preencher 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 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 o cadastro da consulta rápida, deve ser desenvolvido o fonte 4GL com as funções padrões para a execução da mesma no Fluig. Atualmente são necessárias 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. |
Função de START
No 4GL o nome desta função deve ter o sufixo _indicator_start, não poderá possuir parâmetros e deverá retornar para o Fluig uma variável RECORD com as informações de montagem do widget de consulta rápida, como:
- os filtros que poderão ser realizados;
- as colunas que comporão a grade com os dados da consulta;
- a lista de filtros pré-definidos; e
- a lista com o nome dos programas que poderão ser executados a partir da consulta.
Exemplo
Bloco de código | ||||
---|---|---|---|---|
| ||||
#------------------------------#
FUNCTION logi1_indicator_start()
#------------------------------#
DEFINE lr_start RECORD
filters ARRAY[2] OF RECORD
table_name LIKE frm_column.table_name,
column_name LIKE frm_column.column_name
END RECORD,
columns ARRAY[3] OF RECORD
table_name LIKE frm_column.table_name,
column_name LIKE frm_column.column_name,
can_order SMALLINT
END RECORD,
selection ARRAY[3] OF
RECORD
code CHAR(03),
label CHAR(50)
END RECORD,
actions ARRAY[2] OF
RECORD
code CHAR(08),
label CHAR(50)
END RECORD
END RECORD
#Define as colunas de filtro da consulta rápida
LET lr_start.filters[1].table_name = 'log_grupos'
LET lr_start.filters[1].column_name = 'grupo'
LET lr_start.filters[2].table_name = 'log_grupos'
LET lr_start.filters[2].column_name = 'des_grupo'
#Define as colunas da consulta rápida
LET lr_start.columns[1].table_name = 'usuarios'
LET lr_start.columns[1].column_name = 'cod_usuario'
LET lr_start.columns[1].can_order = TRUE
LET lr_start.columns[2].table_name = 'usuarios'
LET lr_start.columns[2].column_name = 'nom_funcionario'
LET lr_start.columns[2].can_order = TRUE
LET lr_start.columns[3].table_name = 'usuarios'
LET lr_start.columns[3].column_name = 'ind_admlog'
LET lr_start.columns[3].can_order = FALSE
#Define quais valores estarão na seleção de filtros
LET lr_start.selection[1].code = '*'
LET lr_start.selection[1].label = 'Todos os usuários'
LET lr_start.selection[2].code = 'S'
LET lr_start.selection[2].label = 'Somente administradores'
LET lr_start.selection[3].code = 'N'
LET lr_start.selection[3].label = 'Somente usuários comuns'
#Define quais programas poderão ser chamados pela consulta
LET lr_start.actions[1].code = 'log02700'
LET lr_start.actions[1].label = 'Usuários'
LET lr_start.actions[2].code = 'log02720'
LET lr_start.actions[2].label = 'Grupos do usuário'
RETURN lr_start
END FUNCTION |
A execução da função acima possibilitará a inicialização do widget de consulta rápida, 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, 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.
Todos estes parâmetros devem ser considerados ao executar a consulta no banco de dados e o retorno deve ser uma variável RECORD com:
- os dados da consulta;
- quantidade total de registros encontrados no banco de dados;
- quantidade total de registros que serão retornado para o Fluig;
- número total de páginas conforme a consulta efetuada; e
- número da página atual de consulta.
Exemplo
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 FWQVLOGIX_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 FWQVLOGIX_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 |
Função GET-DATA
Informações |
---|
A tecnica apresentada aqui foi pensada para reduzir ao máximo a necessidade de alteração dos programas já construidos, motivada pela inclusão de novos parâmetros. Por isso, é apresentada a passagem dos mesmos usando a função _ADVPL_FWQVSetParametersLogix(), cuja chamada também é realizada pelo serviço REST responsável por chamar o programa de consulta rápida da área de negócio/segmento. |
Esta função deve ser criada quando houver necessidade de tratar filtros customizados do widget de consulta rápida. Ela será executada quando estiver presente no 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_FWQVGetParameterLogix("nome_do_parametro"), onde "nome_do_parâmetro" é o identificador do campo dentro da área de memória compartilhada que contem o valor desejado.
Quando da criação dessa função, o corpo da função SEARCH deve ser transferido para ela, 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
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:
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
A variável RECORD deve ser preenchida com os valores correspondentes antes de ser passada como parâmetro para a função _ADVPL_FWQVSetParametersLogix(<variavel_record>). Lembre-se de inicializar a variável RECORD antes de atribuir valores aos 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_FWQVSetParametersLogix().
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_FWQVSetParametersLogix(lr_params) # Grava os parâmetros na área compartilhada
RETURN logi1_indicator_get_data() # O retorno da função search é o mesmo da get_data
END FUNCTION |
Recebendo dados na função GET-DATA
Os dados atribuidos à área de memória compartilhada são recuperados através da função _ADVPL_FWQVGetParameterLogix("nome_do_parametro"), onde nome_do_parametro deve ser exatamente igual ao campo da variável RECORD que se deseja recuperar.
Exemplo
Trecho da função GET-DATA onde é feita a recuperação dos parâmetros.
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_FWQVGetParameterLogix("l_searchcol")
LET l_filter_value = _ADVPL_FWQVGetParameterLogix("l_searchval")
LET l_selection = _ADVPL_FWQVGetParameterLogix("l_selection")
LET l_sort_col = _ADVPL_FWQVGetParameterLogix("l_sortcol")
LET l_sort_order = _ADVPL_FWQVGetParameterLogix("l_sortorder")
LET l_rows = _ADVPL_FWQVGetParameterLogix("l_rows")
LET l_page = _ADVPL_FWQVGetParameterLogix("l_page")
LET l_customfilter = _ADVPL_FWQVGetParameterLogix("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... |
Aplicando o filtro customizado
O valor informado no parâmetro customfilter deve estar de acordo com a sintaxe SQL usada no 4GL e sua aplicação na pesquisa não requer tratamento especifico. Ou seja, caso o conteúdo do parâmetro customfilter não esteja correto, não é 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.
Bloco de código |
---|
# ...trecho inicial da função get_data...
#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
# Adiciona o filtro customizado informado na consulta rapida
IF l_customfilter IS NOT NULL THEN
LET l_where_clause = l_where_clause CLIPPED," AND ",l_customfilter 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
# ...continuação do codigo da função get_data... |
Função AUTO-COMPLETE
No 4GL o nome desta função deve ter o sufixo _indicator_autocomplete, deve ter como parâmetro:
- nome da coluna selecionada para filtro; e
- o valor do filtro informado pelo usuário.
O retorno deve ser uma variável RECORD com:
- os dados da consulta; e
- o total de registros encontrados no banco de dados.
Exemplo
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 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", " 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 FWQVLOGIX_consoleDebugMessage(l_sql_stmt) CALL log0030_processa_err_sql("PREPARE SQL","var_indicator_autocomplete",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:
Posicionamento automático no registro selecionado
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 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.
Exemplo
Bloco de código | ||||
---|---|---|---|---|
| ||||
#-----------------#
FUNCTION log02720()
#-----------------#
DEFINE l_usuario LIKE log_usu_grupos.usuario
IF LOG_initApp("PADRAO") > 0 THEN
RETURN
END IF
LET m_form_reference = _ADVPL_create_component(NULL,"LFORMMETADATA",m_container_reference)
CALL _ADVPL_set_property(m_form_reference,"FORM","log02720",mr_log_usu_grupos,ma_log_usu_grupos)
#Verifica se há um argumento de execução para o programa
IF APPLICATION_getNumArgs() > 0 THEN
IF APPLICATION_getArg("action") = "INDICATOR" AND UPSHIFT(APPLICATION_getArg("indicator")) = "LOGI1" THEN
LET l_usuario = DOWNSHIFT(APPLICATION_getArg("cod_usuario"))
END IF
END IF
IF l_usuario IS NOT NULL THEN
CALL _ADVPL_get_property(m_form_reference,"EXECUTE_OPERATION","FIND","a.usuario='"||l_usuario CLIPPED||"'")
ELSE
CALL _ADVPL_set_property(m_form_reference,"ACTIVATE",TRUE)
END IF
END FUNCTION |
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.