Olá,
A situação ocorre por conta do formato do json que a API que você consome retorna.
A API retorna o seguinte JSON:
{
"USD":{
"code":"USD",
"codein":"BRL",
"name":"Dólar Comercial",
"high":"5.1604",
"low":"5.16",
"varBid":"0.0003",
"pctChange":"0",
"bid":"5.1596",
"ask":"5.1603",
"timestamp":"1608676149",
"create_date":"2020-12-22 21:00:02"
}
}
Perceba que os dados code
, name
entre outros, estão dentro de um objeto chamado USD
no meu caso.
Para acessar então essas propriedades, você precisa então acessar primeiro o objeto USD
do JSON, para depois obter os demais dados.
Ficaria mais ou menos da seguinte forma:
CGET2 := oJson["USD"]:GetJsonObject('codein')
CGET3 := oJson["USD"]:GetJsonObject('name')
CGET4 := oJson["USD"]:GetJsonObject('high')
CGET5 := oJson["USD"]:GetJsonObject('low')
CGET6 := oJson["USD"]:GetJsonObject('varBid')
CGET7 := oJson["USD"]:GetJsonObject('pctChange')
CGET8 := oJson["USD"]:GetJsonObject('bid')
CGET9 := oJson["USD"]:GetJsonObject('ask')
CGET10 := oJson["USD"]:GetJsonObject('timestamp')
CGET11 := oJson["USD"]:GetJsonObject('create_date')
Porém nesse exemplo, o USD está como hardcode, o correto seria você ter um dado dinâmico aí, conforme o valor informado no code
de sua dialog.
Modificando o seu código, ficaria mais ou menos da seguinte forma:
#include "protheus.ch"
// ----------------------------------------------------------------------
/*/{Protheus.doc} cotMoeda
Cotação de moedas
@author carlostr
@since 22/12/2020
@version 1.0
/*/
// ----------------------------------------------------------------------
user function cotMoeda()
local oDlg1 as object
local oSay1 as object
local oSay2 as object
local oSay3 as object
local oSay4 as object
local oSay5 as object
local oSay6 as object
local oSay7 as object
local oSay8 as object
local oSay9 as object
local oSay10 as object
local oSay11 as object
local oButton1 as object
local oButton2 as object
local oButton3 as object
local oFont1 as object
local oFont2 as object
local lDlg as logical
local cSpace8 as char
local oGet1 as object
local oGet2 as object
local oGet3 as object
local oGet4 as object
local oGet5 as object
local oGet6 as object
local oGet7 as object
local oGet8 as object
local oGet9 as object
local oGet10 as object
local oGet11 as object
private cGet1 as char
private cGet2 as char
private cGet3 as char
private cGet4 as char
private cGet5 as char
private cGet6 as char
private cGet7 as char
private cGet8 as char
private cGet9 as char
private cGet10 as char
private cGet11 as char
cSpace8 := space(8)
cGet1 := cSpace8
cGet2 := cSpace8
cGet3 := cSpace8
cGet4 := cSpace8
cGet5 := cSpace8
cGet6 := cSpace8
cGet7 := cSpace8
cGet8 := cSpace8
cGet9 := cSpace8
cGet10 := cSpace8
cGet11 := cSpace8
lDlg := .T.
while lDlg
oFont1 := TFont():new("Comic Sans MS",,14,,.F.,,,,,.F.,.F.)
oFont2 := TFont():new("Arial Black",,14,,.F.,,,,,.F.,.F.)
oDlg1 := TDialog():new(0,0,325,400,"Cotações de Moedas.",,,,,CLR_BLACK,CLR_WHITE,,,.T.)
oGroup1 := TGroup():new(002,005,160,200,"Cotações de Moedas",oDlg1,,,.T.)
oSay1 := TSay():new(10,10,{||"Code"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet1 := TGet():new(10,30,{|u|IIF(PCount()>0,cGet1:=u,cGet1)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.F.,.F.,,cGet1,,,,)
oSay2 := TSay():new(25,10,{||"Codein"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet2 := TGet():new(25,30,{|u|IIF(PCount()>0,cGet2:=u,cGet2)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.F.,.F.,,cGet2,,,,)
oSay3 := TSay():new(40,10,{||"Name"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet3 := TGet():new(40,30,{|u|IIF(PCount()>0,cGet3:=u,cGet3)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.T.,.F.,,cGet3,,,,)
oSay4 := TSay():new(55,10,{||"High"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet4 := TGet():new(55,30,{|u|IIF(PCount()>0,cGet4:=u,cGet4)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.T.,.F.,,cGet4,,,,)
oSay5 := TSay():new(70,10,{||"Low"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet5 := TGet():new(70,30,{|u|IIF(PCount()>0,cGet5:=u,cGet5)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.T.,.F.,,cGet5,,,,)
oSay6 := TSay():new(85,10,{||"Varbid"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet6 := TGet():new(85,30,{|u|IIF(PCount()>0,cGet6:=u,cGet6)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.T.,.F.,,cGet6,,,,)
oSay7 := TSay():new(100,10,{||"Pctchange"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet7 := TGet():new(100,30,{|u|IIF(PCount()>0,cGet7:=u,cGet7)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.T.,.F.,,cGet7,,,,)
oSay8 := TSay():new(10,100,{||"Bid"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet8 := TGet():new(10,120,{|u|IIF(PCount()>0,cGet8:=u,cGet8)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.T.,.F.,,cGet8,,,,)
oSay9 := TSay():new(25,100,{||"Ask"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet9 := TGet():new(25,120,{|u|IIF(PCount()>0,cGet9:=u,cGet9)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.T.,.F.,,cGet9,,,,)
oSay10 := TSay():new(40,100,{||"Time"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet10 := TGet():new(40,120,{|u|IIF(PCount()>0,cGet10:=u,cGet10)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.T.,.F.,,cGet10,,,,)
oSay11 := TSay():new(55,100,{||"Data"},oDlg1,,oFont1,,,,.T.,CLR_RED,CLR_WHITE,300,20)
oGet11 := TGet():new(55,120,{|u|IIF(PCount()>0,cGet11:=u,cGet11)},oDlg1,60,10,"@!",,0,,,.F.,,.T.,,.F.,,.F.,.F.,,.T.,.F.,,cGet11,,,,)
oButton1 := TButton():new(140,10,"&Consulta",oDlg1,{||cMoeda(oGet1)},50,15,,,.F.,.T.,.F.,,.F.,,,.F.)
oButton2 := TButton():new(140,75,"&Atualiza Moeda",oDlg1,{||grava()},50,15,,,.F.,.T.,.F.,,.F.,,,.F.)
oButton3 := TButton():new(140,142,"&Fechar",oDlg1,{||lDlg := .F., oDlg1:end()},50,15,,,.F.,.T.,.F.,,.F.,,,.F.)
oDlg1:activate(,,,.T.)
enddo
return
// ----------------------------------------------------------------------
/*/{Protheus.doc} cMoeda
Consulta a API de cotação de moedas e atualiza a dialog com os valores
@param oGetCode TGet do código da moeda
@author carlostr
@since 22/12/2020
@version 1.0
/*/
// ----------------------------------------------------------------------
static function cMoeda(oGetCode)
local cURL as char
local cPath as char
local oRest as object
local cBRL as char
local cJSON as char
local cCode as char
local jJson
local cParser as char
if Empty(cGet1)
msgAlert("Campo não pode estar em branco.", "Campo em Branco")
oGetCode:setFocus()
return
endif
//https://economia.awesomeapi.com.br/json/all/USD-BRL
cURL := "https://economia.awesomeapi.com.br/json/all/"
cBRL := "-BRL"
jJson := JsonObject():new()
oRest := FWRest():new(cURL)
cCode := allTrim(upper(cGet1))
cPath := cCode + cBRL
oRest:setPath(cPath)
if oRest:get()
cJSON := decodeUtf8(oRest:getResult())
cParser := jJson:fromJson(cJSON)
if empty(cParser)
cGet2 := jJson[cCode]["codein"]
cGet3 := jJson[cCode]["name"]
cGet4 := jJson[cCode]["high"]
cGet5 := jJson[cCode]["low"]
cGet6 := jJson[cCode]["varBid"]
cGet7 := jJson[cCode]["pctChange"]
cGet8 := jJson[cCode]["bid"]
cGet9 := jJson[cCode]["ask"]
cGet10 := jJson[cCode]["timestamp"]
cGet11 := jJson[cCode]["create_date"]
msgInfo(cJSON, "Sucesso")
else
msgStop("Ocorreu um erro no retorno da API:" + CRLF + cParser, "Erro")
endif
else
msgStop(oRest:getLastError(), "Erro")
endif
freeObj(oRest)
return
// ----------------------------------------------------------------------
/*/{Protheus.doc} grava
Efetua a persistência da cotação da moeda
@author carlostr
@since 22/12/2020
@version 1.0
/*/
// ----------------------------------------------------------------------
static function grava()
conOut("TODO: Criar a gravacao...")
return
Eu fiz a remoção de algumas variáveis private, mas com carinho dá pra remover todas :)