Jump to content
Fivewin Brasil

Geraldo (gbsilva)

Membros
  • Posts

    1,495
  • Joined

  • Last visited

  • Days Won

    6

Everything posted by Geraldo (gbsilva)

  1. Pessoal achei uma solução parcial, mas gostaria de explicar o motivo pelo qual estava tentando fazer esse método. Alguns dos meus fontes uso para complilar com a Sqllib ou TDolphin, então estou tentando otimizá-los, pois em determinados pontos tenho que escrever muitas linhas. Estou postando aqui um modo que fiz com meu pouco conhecimento para economizar um pouco e padronizar os fontes. Exemplo real: 1) Atualmente faço assim: //-> (I) faço o SELECT cQry := "SELECT ...." //-> (II) depois faço assim #ifdef rdd_sqllib //-> se for sqllib assim aQry := SqlArray(cQry) nQry := Len(aQry) #else //-> se for tDolphin uso assim oQry := oServer:Query(cQry) nQry := oQry:Lastrec() #endif if nQry = 0 GbMsg("Nenhum funcionário localizado!",,2) return(.f.) endif //-> (III) o resultado vai para um array também dependendo da RDD #ifdef rdd_sqllib for i = 1 to nQry aAdd(::aFuncionarios,{aQry[i,1],; Padr(aQry[i,2],50),; Padr(aQry[i,3],30),; aQry[i,4],; aQry[i,5],; aQry[i,6],; Padr(aQry[i,7],10),; Padr(aQry[i,8],10),; Padr(aQry[i,9],100),; Padr(aQry[i,10],10),; aQry[i,11],; Padr(aQry[i,12],80),; Padr(aQry[i,13],30),; aQry[i,14],; Padr(aQry[i,15],8),; Padr(aQry[i,16],11),; Padr(aQry[i,17],12),; Gbdataf(aQry[i,18]),; aQry[i,19],; aQry[i,20],; aQry[i,21],; Padr(aQry[i,22],10),; Padr(aQry[i,23],20),; aQry[i,24],; aQry[i,25],; aQry[i,26] } ) next #else While !oQry:Eof() aAdd(::aFuncionarios,{oQry:FieldGet(1),; oQry:FieldGet(2),; oQry:FieldGet(3),; oQry:FieldGet(4),; oQry:FieldGet(5),; oQry:FieldGet(6),; oQry:FieldGet(7),; oQry:FieldGet(8),; oQry:FieldGet(9),; oQry:FieldGet(10),; oQry:FieldGet(11),; oQry:FieldGet(12),; oQry:FieldGet(13),; oQry:FieldGet(14),; oQry:FieldGet(15),; oQry:FieldGet(16),; oQry:FieldGet(17),; oQry:FieldGet(18),; oQry:FieldGet(19),; oQry:FieldGet(20),; oQry:FieldGet(21),; oQry:FieldGet(22),; oQry:FieldGet(23),; oQry:FieldGet(24),; oQry:FieldGet(25),; oQry:FieldGet(26) } ) oQry:Skip() End oQry:End() #endif 2) Aqui as melhorias ************************************************************************** //-> Criei dois métodos para substituir todo esse código acima apenas assim: //-> (II) executa o select sem especificar #ifdef que esta no método ::ExecuteQry(cQry) if !::ExecuteQry(cQry) GbMsg("Nenhum funcionário localizado!",,2) endif /* (III) Esse é o melhor, ou seja, adiciono a mesma array com apenas uma chamada ao método ::gbLoad(aArray) e economizo um monte de linhas */ if !::gbLoad(::aFuncionarios) return(.f.) endif O outro método que estou tentando fazer é porque quando uso Sqllib um determinado campo texto, por exemplo nome de tamanho 80 quando uso SqlArray ele retorna o tamanho sem os espações, ou seja, 20, 30 mas nunca o tamanho real do campo na tabela, por isso tenho de usar o Padr(vetor[i,1],80). A TDolphin ao contrário retorna o tamanho real do campo, como não achei uma solução melhor vou usar Padr() em todos, pois a idéia inicial era usar só para Sqllib, mas acho que dará certo indepedente da RDD. O método gbLoad() tem outras funções, por exemplo, carregar dados na DbCombo, apenas incluindo mais duas arrays na chamada e alguns outros parâmetros e usar como abaixo, pois com a TDolphin não funciona a DbCombo com alias (pelo menos foi o que me disse o Daniel há um tempo atras). REDEFINE DBCOMBO oCad[8] VAR oFunc:registro ID 101 OF oDlg ; ITEMS aFunc LIST alFunc oCad[8]:oFont := oFont Agradeço a todos, mas se alguém tiver alguma idéia sugestóes serão bem vindas. Sds,
  2. Pessoal estou precisando criar um método numa classe para igualar dinamicamente atributos de uma classe a valores de uma array: Imagine que tenho uma array com os seguintes valores e posições: //-> esses valores eu obtenho de uma tabela e carrego na array, aqui é só um exemplo aQyr := {10,"Aqui um texto",34,"Outro texto"} No método eu passaria em primeiro o nome do meu atributo e a posição na array a qual seria atribuida a ele :: Obter( { {::codigo,aQry[1,1]},; {::texto1,aQry[1,2]},; {::valor,aQry[1,3]},; {::texto2,aQry[1,4]} } ) e depois ao chamar os atributos retornaria isso ::codigo seria 10, ::texto1 seria "Aqui é um texto" etc. Em outra situação carregaria minha array aQry com outros valores e depois chamaria como acima, ou seja, seja um método genérico para várias ocasiões. aQyr := {3,"Geraldo","Silva"} No método eu passaria em primeiro o nome do meu atributo e a posição na array a qual seria atribuida a ele :: Obter( { {::id,aQry[1,1]},; {::nome,aQry[1,2]},; {::sobrenome,aQry[1,3]} } ) ao chamar esses novos atributods deveria retornar ::id seria 3 ::nome seria "Geraldo" e ::sobrenome seria "Silva" Tentei fazer assim, mas não deu certo, o valor é passado corretamente, mas não consigo recuperá-lo pelo atributo. METHOD Obter(uValues) CLASS TGbSoftware local i for i = 1 to Len(uValues) uValues[1] := uValues[2] //-> aqui eu queria que o nome do atributo passado fosse igualado a posição 2 do array, isso até é feito, mas não consigo recuperá-lo como disse acima next return(.t.) Gostaria que após chamar o método ao fazer um teste assim, por exemplo: ? ::nome me retornasse o "Geraldo" Será que existe um meio de se fazer isso Agradeço atencipadamente. Sds,
  3. Luiz algo assim não funcionaria? SELECT res.cliente, res.maiordata, res.valor FROm (SELECT v.cliente, max(v.data) AS maiordata, v.valor, v.sql_rowid FROM vendas v GROUP BY v.cliente HAVING maiordata < (sua_variavel) ) res ORDER BY res.cliente, res.sql_rowid desc ;
  4. Perfeito funcionou direitinho. Muito obrigado Theotokos.
  5. Pessoal como faço para aparecer a barra de rolagem horizontal usando a custom control. Uso Pelles; oBrw:nHeaderHeight := 30 oBrw:nDataLines := 1.2 oBrw:nFooterlines := 1 oBrw:lFooter := .T. Obs. Tem rodapé no browse, aparece normal, mas a barra não consegui. Grato,
  6. Luiz tudo bem! Nunca vi um FROM assim? Achei estranho também tem um SUM(), mas não tem GROUP BY. //-> Eu uso bastante e fica assim, esse é apenas um exemplo: SELECT a.produto, b.descricao, SUM(c.qtde) AS qtde FROM tab1 AS a LEFT JOIN tab2 AS b ON a.chaves = b.chave LEFT JOIN tab3 AS c ON a.chave = c.chave LEFT JOIN // ou INNER JOIN // select interno ( SELECT chave,codigo,campo3 FROM tab4 WHERE codigo = '"+cGet[4]+"' ) res // esse res seria o resultado do select interno ON tab1.chave = res.chave // chave da tabela 1 = chave do select interno WHERE ???? // se tiver uma segunda condição coloca aqui pode usar da tab1, tab2, tab3 ou do res GROUP BY a.produto // se tem uma soma tem que ter um group by ORDER BY ??? // se for o caso //-> Esse é um SELECT em produção e tem praticamente a mesma lógica, no caso em SQL Server no php, mas a lógica é a mesma. SELECT EXT.id_grupo_empresa, EMP.nome_contrato, EXT.nome, EXT.titulo_servico, RES.es, RES.at, FUN.telefone FROM GCORE..TAB_DADOS_ACQ_EXT EXT INNER JOIN GCORE_CAD_EMPRESAS_AREAS..cad_func FUN ON EXT.re_fisc = FUN.re_fisc INNER JOIN GCORE_CAD_EMPRESAS_AREAS..cad_empresa_contrato EMP ON EXT.id_empresa_contrato = EMP.id_empresa_contrato INNER JOIN (SELECT AMO.acq,AMO.es,AMO.at FROM GCORE..TAB_DADOS_AMOSTRAS_1 AMO UNION ALL SELECT BDLP.acq,BDLP.es,BDLP.at FROM GCORE..TAB_DADOS_AMOSTRAS_BD_LP BDLP UNION ALL SELECT DDR.acq,DDR.es,DDR.at FROM GCORE..TAB_DADOS_AMOSTRAS_DDR DDR UNION ALL SELECT PZ.acq,PZ.es,PZ.at FROM GCORE..TAB_DADOS_AMOSTRAS_PZ PZ UNION ALL SELECT LIMP.acq,LIMP.es,LIMP.at FROM GCORE..TAB_DADOS_AMOSTRAS_TUP_LIMP LIMP ) RES ON EXT.acq = RES.acq WHERE Convert(CHAR(10),EXT.data_fisc,103) = '$data' AND EXT.id_prod NOT IN (38,40) AND EXT.re_fisc NOT IN (1063880,50009,50152,340540) AND EXT.titulo_servico <> 'ESP ADSL AUTOINS' AND EXT.status NOT IN(8) AND EXT.titulo_servico NOT like '%REINSPEÇÃO%' GROUP BY EXT.id_grupo_empresa, EMP.nome_contrato, EXT.nome, RES.es, RES.at, EXT.titulo_servico, FUN.telefone ORDER BY EXT.id_grupo_empresa, EMP.nome_contrato, EXT.nome, RES.es, RES.at, EXT.titulo_servico ; Espero ter ajudado. Sds,
  7. Pessoal deixa eu aproveitar o tópico, cor no Group tudo bem, mas e a fonte em tempo de execução. Tentei colocar uma fonte maior e não deu certo, aparece as duas o texto que esta na dialog e o texto sobreposto pelo novo tamanho da fonte. se coloco nFont fica normal se tento sFont que é maior fica as duas mensagens. Abaixo como tentei: DEFINE FONT nFont NAME "Ms Sans Serif" SIZE 0,-10 DEFINE FONT sFont NAME "Time New Roman" SIZE 0,16 BOLD REDEFINE GROUP oGroup ID 4002 OF oDlg PROMPT "Novo Titulo do Group" FONT sFont TRANSPARENT COLOR CLR_HRED
  8. Pessoal no Xp não é possível instalar a versão 8 32 bits? Grato,
  9. Obrigado Alessandro, mas eu sempre usei o pelles, apenas estou com um versão bem antiga. Vou testar essa versão 8.0 32 bit
  10. Gilberto como o Alessandro ainda não viu novamente esse post, que versão você usa atualmente. Grato, Geraldo
  11. Alessandro como vai meu amigo. Eu também ainda uso a versão 4.5 rss essa versão 8.0 tá rodando belezinha... Abs,
  12. Daniel abusando da sua boa vontade, fiquei em dúvida no seu fonte, coloquei em vermelho algumas dúvidas, como exatamente ele funciona? É que me pareceu tão simples, talvez eu possa adaptar para o meu atualizador. Grato, //-> cFile seria o nome do seu executável Function main(cFile) local cFileName , ntentativa syswait(1.7) ntentativa :=1 //-> de onde vem esse tmp.exe ? como você passa ele para a função ? if file('tmp.exe') while .t. //-> tenta apagar o cFile até 20 vezes if FErase( cFile ) == -1 syswait(1.7) SendMessage( FindWindow( 0, "CiaCpd - Aplicativos e Sistemas - Desde 1992" ), WM_CLOSE ) ntentativa++ if ntentativa > 20 nMsgBox( "Não foi possível criar o arquivo.", "Atenção" ) return nil endif loop endif //-> Dúvida você não deletou o cFile? como atribui ao cFileName cFileName:=cFileName(cFile) //-> Aqui tudo bem renomeia o tmp.exe para nome do cFileName exceto a obs anterior FRename('tmp.exe',cFileName) exit enddo EndIf //-> executa o arquivo WinExec( cFileName ) PostQuitMessage(0) Quit Return NIL
  13. Daniel obrigado pela dica, farei isso sim pode ter certeza e também obrigado pelo fonte. Sds,
  14. Obrigado a todos. Na realidade são algumas máquinas, hoje estive fora, mas segunda vou ver as permissões com o pessoal do TI de lá e também vou aproveitar e dar uma olhada nas dicas postadas. Agradeço a todos e assim que verificar volto com o resultado. Sds,
  15. Pessoal mais uma coisa aceito sugestões de como atualizar, hoje posto no servidor o executável com a nova versão e quando o usuário acessa se tiver uma nova versão, atualiza o executável na máquina local. Grato,
  16. Pessoal estou tendo problemas para atualizar a versão do sistema. No XP funciona normalmente, mas no Win7 dá erro, alguém faz atualização com Win7. Uso esse código há muito tempo e apesar de meio ultrapassado funciona. Tentei modernizar um pouco e fiz uma pequena classe, mas também não deu certo no Win7.
  17. Tenta assim: oExcel:Sheets:Add() obs. não testei
  18. Não uso atualmente, mas já usei assim: Static function CarregaFiscal(oCpo,aLista) Local nP,cSql,oCarga,lData:=space(12),nLista:=Len(aLista),dLote:=ctod("") If nLista > 0 For nP = 1 to nLista DelMatriz(aLista,oBrw:nArrayAt) Next Endif cSql := "SELECT re,nome,telefone,cargo,id_supervisor,status,apelido,setor " cSql += " FROM cad_func ORDER BY nome ; " oCarga := TDbOdbcDirect():new( cSql,oOdbc) oCarga:Open() If empty(oCarga:FieldGet(1)) oCarga:End() GbMsg("Nenhum registro selecionado!",,2) // GbFoco(oCad[1]) return(.f.) Endif While !oCarga:Eof() aAdd(aLista,{oCarga:FieldGet(1),oCarga:FieldGet(2) } ) oCarga:Skip() End oCarga:End() return(.t.)
  19. Olá Pablo tudo bem! Eu compilei há um certo tempo, mas anotei como fiz e foi assim e tenho utilizado a lib normalmente. Você seta onde esta o seu xH 1.2.1 e veja se ajuda. Data: 07/09/2012 Para gerar lib do TDolphin basta executar o arquivo setenvx.bat na pasta TDolphin_Original que será criada a lib na pasta lib\XHARBOUR\BCC\ com o nome dolphin.lib Contéudo do arquivo para meus path´s @CALL CLEANENV.BAT @SET PRG_COMPILER=XHARBOUR @SET PRG_COMP_PATH=C:\xHarbour_Fwh1201 @SET PRG_COMP_BIN_PATH=%PRG_COMP_PATH%\bin @SET PRG_COMP_LIB_PATH=%PRG_COMP_PATH%\lib @SET PRG_COMP_INC_PATH=%PRG_COMP_PATH%\include @SET C_COMPILER=BCC @SET C_COMP_PATH=c:\bcc582 @SET C_COMP_BIN_PATH=%C_COMP_PATH%\bin @SET C_COMP_LIB_PATH=%C_COMP_PATH%\lib;%C_COMP_PATH%\lib\psdk @SET C_COMP_INC_PATH=%C_COMP_PATH%\include @SET DOLPHIN_INC=.\include @CALL win-make Sds,
  20. João valeu pelas dicas, vou testar, mas fiz um teste com arquivo no samples e fica de um tamanho absurdo o pdf. Fiz um provisório com php e a classe fpdf até ver se consigo fazer algo com five. Grato,
  21. Olá amigos como faço para gerar o arquivo e salvá-lo numa pasta em vez de imprimir e como PDF usando a TPrinter. Se existir outro modo também estou dispoto a testar. Grato,
  22. Gibaf acho que tanto faz, veja a classe TOleauto() método new(): * * * Descripción: Clase TOleAuto() * * * * Autor: José F. Giménez (JFG) - jfgimenez@wanadoo.es * * tecnico.sireinsa@ctv.es * * Fecha: 6-11-2000 * * * * Revisado: 13-2-2001, 28-2-2001, 13-3-2001 * * * * Nota: basado en la clase TComObj() de FW 2.1 * * * ************************************************************************** #ifndef __HARBOUR__ #include "FiveWin.ch" #else #include "HBClass.ch" #endif CLASS TOleAuto DATA hObj METHOD New( cAutoObj ) CONSTRUCTOR METHOD End() METHOD Invoke( cMember, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6, uParam7 ) METHOD Set( cProperty, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6, uParam7 ) METHOD Get( cProperty, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6, uParam7 ) ERROR HANDLER OnError( cMsg, nError ) ENDCLASS //-------------------------------------------------------------------- METHOD New( uObj ) CLASS TOleAuto IF ValType( uObj )="C" ::hObj := CreateOleObject( uObj ) ELSE ::hObj := uObj ENDIF RETURN Self //-------------------------------------------------------------------- METHOD End() CLASS TOleAuto ::hObj := NIL OLEUninitialize() RETURN NIL //-------------------------------------------------------------------- METHOD Invoke( cMethod, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 , uParam7 ) CLASS TOleAuto LOCAL uObj IF uParam7 != NIL uObj := OLEInvoke( ::hObj, cMethod, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 , uParam7 ) ELSEIF uParam6 != NIL uObj := OLEInvoke( ::hObj, cMethod, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 ) ELSEIF uParam5 != NIL uObj := OLEInvoke( ::hObj, cMethod, uParam1, uParam2, uParam3, uParam4, uParam5 ) ELSEIF uParam4 != NIL uObj := OLEInvoke( ::hObj, cMethod, uParam1, uParam2, uParam3, uParam4 ) ELSEIF uParam3 != NIL uObj := OLEInvoke( ::hObj, cMethod, uParam1, uParam2, uParam3 ) ELSEIF uParam2 != NIL uObj := OLEInvoke( ::hObj, cMethod, uParam1, uParam2 ) ELSEIF uParam1 != NIL uObj := OLEInvoke( ::hObj, cMethod, uParam1 ) ELSE uObj := OLEInvoke( ::hObj, cMethod ) ENDIF IF OleIsObject() RETURN TOleAuto():New( uObj ) ELSEIF Ole2TxtError() == "DISP_E_EXCEPTION" OLEShowException() RETURN Self ELSEIF OleError() != 0 MsgAlert( cMethod + ": " + Ole2TxtError(), "OLE Error" ) MsgInfo( ValType( uObj ) ) ENDIF RETURN uObj //-------------------------------------------------------------------- METHOD Set( cProperty, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 , uParam7 ) CLASS TOleAuto LOCAL uObj IF uParam7 != NIL OLESetProperty( ::hObj, cProperty, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6, uParam7 ) ELSEIF uParam6 != NIL OLESetProperty( ::hObj, cProperty, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 ) ELSEIF uParam5 != NIL OLESetProperty( ::hObj, cProperty, uParam1, uParam2, uParam3, uParam4, uParam5 ) ELSEIF uParam4 != NIL OLESetProperty( ::hObj, cProperty, uParam1, uParam2, uParam3, uParam4 ) ELSEIF uParam3 != NIL OLESetProperty( ::hObj, cProperty, uParam1, uParam2, uParam3 ) ELSEIF uParam2 != NIL OLESetProperty( ::hObj, cProperty, uParam1, uParam2 ) ELSEIF uParam1 != NIL OLESetProperty( ::hObj, cProperty, uParam1 ) ENDIF IF Ole2TxtError() == "DISP_E_EXCEPTION" OLEShowException() ELSEIF OleError() != 0 MsgAlert( cProperty + ": " + Ole2TxtError(), "OLE Error" ) ENDIF RETURN nil //-------------------------------------------------------------------- METHOD Get( cProperty, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 , uParam7 ) CLASS TOleAuto LOCAL uObj IF uParam7 != NIL uObj := OLEGetProperty( ::hObj, cProperty, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 , uParam7 ) ELSEIF uParam6 != NIL uObj := OLEGetProperty( ::hObj, cProperty, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 ) ELSEIF uParam5 != NIL uObj := OLEGetProperty( ::hObj, cProperty, uParam1, uParam2, uParam3, uParam4, uParam5 ) ELSEIF uParam4 != NIL uObj := OLEGetProperty( ::hObj, cProperty, uParam1, uParam2, uParam3, uParam4 ) ELSEIF uParam3 != NIL uObj := OLEGetProperty( ::hObj, cProperty, uParam1, uParam2, uParam3 ) ELSEIF uParam2 != NIL uObj := OLEGetProperty( ::hObj, cProperty, uParam1, uParam2 ) ELSEIF uParam1 != NIL uObj := OLEGetProperty( ::hObj, cProperty, uParam1 ) ELSE uObj := OLEGetProperty( ::hObj, cProperty ) ENDIF IF Ole2TxtError() $ "DISP_E_MEMBERNOTFOUND | DISP_E_BADPARAMCOUNT | " + ; "DISP_E_EXCEPTION" uObj := ::Invoke( cProperty, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 , uParam7 ) ELSE IF OleIsObject() RETURN TOleAuto():New( uObj ) ELSEIF OleError() != 0 MsgAlert( cProperty + ": " + Ole2TxtError(), "OLE Error" ) ENDIF ENDIF RETURN uObj //-------------------------------------------------------------------- #ifndef __HARBOUR__ METHOD OnError( cMsg, nError ) CLASS TOleAuto LOCAL uParam1 := GetParam( 1, 1 ) LOCAL uParam2 := GetParam( 1, 2 ) LOCAL uParam3 := GetParam( 1, 3 ) LOCAL uParam4 := GetParam( 1, 4 ) LOCAL uParam5 := GetParam( 1, 5 ) LOCAL uParam6 := GetParam( 1, 6 ) LOCAL uParam7 := GetParam( 1, 7 ) #else METHOD OnError( uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 , uParam7 ) CLASS TOleAuto LOCAL cMsg := __GetMessage() #endif LOCAL uObj IF LEFT( cMsg, 1 ) == '_' ::Set( SUBS( cMsg, 2 ), uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 , uParam7 ) ELSE uObj := ::Get( cMsg, uParam1, uParam2, uParam3, uParam4, uParam5, uParam6 , uParam7 ) ENDIF RETURN uObj
  23. Outra seria fazer um select interno agrupando e pegando apenas a última data e agrupando por fornecedor e data e depois exibindo o resultado. SELECT concat(res.fornecedor,'-',f.razao), date_format(res.data,'%d/%m/%Y'), res.qtd, res.valor FROM forne as f INNER JOIN ( SELECT fornecedor, max(data) AS data, qtd, valor WHERE data BETWEEN +Any2Sql(cGet[3]) AND +Any2Sql(cGet[4]) GROUP BY fornecedor, data ) res ON res.fornecedor = f.codigo ORDER BY res.fornecedor, res.data asc ; Sds,
  24. Mais uma tentativa usar com o GROUP BY fornecedor e data. Antes eu falei da função max() no WHERE e não é deve ser no SELECT. SELECT concat(pe.fornecedor,'-',f.razao),date_format(max(pe.data),'%d/%m/%Y'),pe.qtd,pe.valor FROM pedido as pe" LEFT JOIN forne as f on pe.fornecedor = f.codigo" WHERE pe.data >= "+Any2Sql(cGet[3]) AND pe.data <= "+Any2Sql(cGet[4]) AND pe.produto ='"+cGet[1]+"' AND pe.tipo='2' GROUP BY pe.fornecedor, pe.data ORDER BY pe.fornecedor, pe.data asc
×
×
  • Create New...