Nesse vídeo demonstraremos a utilização da classe FWCalendar, que serve para criar um calendário em uma dialog.
Abaixo o código fonte desenvolvido para o exemplo em vídeo acima:
//Bibliotecas #Include "TOTVS.ch" //Posições do array dos agendamentos do calendário #Define ID 1 // Id do Celula #Define OBJETO 2 // Objeto de Tela #Define DATADIA 3 // Data Completa da Celula #Define DIA 4 // Dia Ref. Data da Celula #Define MES 5 // Mes Ref. Data da Celula #Define ANO 6 // Ano Ref. Data da Celula #Define NSEMANO 7 // Semana do Ano Ref. Data da Celula #Define NSEMMES 8 // Semana do Mes Ref. Data da Celula #Define ATIVO 9 // É celula referente a um dia ativo #Define FOOTER 10 // É celula referente ao rodape #Define HEADER 11 // É celula referente ao Header #Define SEMANA 12 // É celula referente a semana #Define BGDefault 13 // Cor de BackGround da Celula /*/{Protheus.doc} User Function zExe209 Tela de agendamentos do Telemarketing @type Function @author Atilio @since 20/02/2023 @version 1.0 @see https://tdn.totvs.com/display/public/framework/FWCalendar @obs **** Apoie nosso projeto, se inscreva em https://www.youtube.com/TerminalDeInformacao **** /*/ User Function zExe209() Local aArea := GetArea() Private aSize := MsAdvSize(.F.) fMontaTela() RestArea(aArea) Return Static Function fMontaTela() Local nCorFundo := 16777215 Local nLargBtn := 50 //Data Private dDtIni := Date() Private cMes := StrZero(Month(dDtIni), 2) Private cAno := StrZero(Year(dDtIni), 4) //Objetos e componentes Private oDlgTmk Private oFwLayer Private oPanTitulo Private oPanCalend Private oPanPreMon Private oPanNexMon Private oPanSair Private oMesAtual Private cMesAno Private cTitHtml //Cabeçalho Private oSayModulo, cSayModulo := 'FAT' Private oSayTitulo, cSayTitulo := 'Calendário de Agendamentos' Private oSaySubTit, cSaySubTit := 'Clique com o botão direito para registrar agendamentos' //Tamanho da janela Private nJanLarg := aSize[5] Private nJanAltu := aSize[6] //Fontes Private cFontUti := "Tahoma" Private oFontMod := TFont():New(cFontUti, , -38) Private oFontSub := TFont():New(cFontUti, , -20) Private oFontSubN := TFont():New(cFontUti, , -20, , .T.) Private oFontBtn := TFont():New(cFontUti, , -14) Private oFontSay := TFont():New(cFontUti, , -12) //Variáveis usadas para atualização das informações Private aInfoDia Private nSelecao Private cTextoSel Private nPosCell //Cria a janela DEFINE MSDIALOG oDlgTmk TITLE "Agendamentos Telemarketing" FROM 0, 0 TO nJanAltu, nJanLarg PIXEL //Criando a camada oFwLayer := FwLayer():New() oFwLayer:init(oDlgTmk,.F.) //Adicionando 3 linhas, a de título, a superior e a do calendário oFWLayer:addLine("TIT", 10, .F.) oFWLayer:addLine("SUP", 05, .F.) oFWLayer:addLine("CAL", 85, .F.) //Adicionando as colunas das linhas oFWLayer:addCollumn("HEADERTEXT", 050, .T., "TIT") oFWLayer:addCollumn("BLANKBTN", 040, .T., "TIT") oFWLayer:addCollumn("BTNSAIR", 010, .T., "TIT") oFWLayer:addCollumn("BLANKSUP1", 015, .T., "SUP") oFWLayer:addCollumn("BTNPREVMONTH", 020, .T., "SUP") oFWLayer:addCollumn("TITLE", 030, .T., "SUP") oFWLayer:addCollumn("BTNNEXTMONTH", 020, .T., "SUP") oFWLayer:addCollumn("COLCAL", 100, .T., "CAL") //Criando os paineis oPanTitulo := oFWLayer:GetColPanel("TITLE", "SUP") oPanCalend := oFWLayer:GetColPanel("COLCAL", "CAL") oPanPreMon := oFWLayer:GetColPanel("BTNPREVMONTH", "SUP") oPanNexMon := oFWLayer:GetColPanel("BTNNEXTMONTH", "SUP") oPanSair := oFWLayer:GetColPanel("BTNSAIR", "TIT") oPanHeader := oFWLayer:GetColPanel("HEADERTEXT", "TIT") //Títulos e SubTítulos oSayModulo := TSay():New(004, 003, {|| cSayModulo}, oPanHeader, "", oFontMod, , , , .T., RGB(149, 179, 215), , 200, 30, , , , , , .F., , ) oSayTitulo := TSay():New(004, 045, {|| cSayTitulo}, oPanHeader, "", oFontSub, , , , .T., RGB(031, 073, 125), , 200, 30, , , , , , .F., , ) oSaySubTit := TSay():New(014, 045, {|| cSaySubTit}, oPanHeader, "", oFontSubN, , , , .T., RGB(031, 073, 125), , 300, 30, , , , , , .F., , ) //Criando os botões oBtnEnd := TButton():New(006, 001, "Fechar", oPanSair, {|| oDlgTmk:End()}, nLargBtn, 018, , oFontBtn, , .T., , , , , , ) //Cria o calendário oCalend := FWCalendar():New( VAL(cMes), VAL(cAno) ) oCalend:aNomeCol := { 'Domingo' , 'Segunda' , 'Terça' , 'Quarta' , 'Quinta' , 'Sexta' , 'Sábado' , 'Semana'} //'Domingo' # 'Segunda' # 'Terça' # 'Quarta' # 'Quinta' # 'Sexta' # 'Sábado' # 'Semana' oCalend:lWeekColumn := .F. oCalend:lFooterLine := .F. oCalend:bLClicked := {|| } oCalend:bLDblClick := {|| } oCalend:bRClicked := {|aInfo, oObj, nRow, nCol| fCliqueDir(aInfo, oObj, nRow, nCol) } fCalendFont() oCalend:Activate( oPanCalend ) //Criando o Say com o mês Atual oMesAtual := TSay():New(0, 0, {|| }, oPanTitulo, , , , , , .T., 20, 20, , , , , , , , .T.) oMesAtual:Align := CONTROL_ALIGN_ALLCLIENT oMesAtual:nClrPane := nCorFundo fMesAno(Val(cMes), Val(cAno)) //Criando o botão do Mês Anterior @ 0, 0 BTNBMP oPrevMonth Resource "PMSSETAESQ" Size 80, 90 Of oPanPreMon Pixel oPrevMontht:cToolTip := "Mes Anterior" //"Mes Anterior" oPrevMonth:bAction := { || FwMsgRun(Nil, {|| fMudaMes(oPanCalend, oCalend, 2 )}, Nil, "Montando calendário...") } //"Montando calendário..." oPrevMonth:Align := CONTROL_ALIGN_RIGHT //Criando o botão do Próximo Mês @ 0, 0 BTNBMP oNextMonth Resource "PMSSETADIR" Size 90, 90 Of oPanNexMon Pixel oNextMonth:cToolTip := "Proximo Mes" //"Proximo Mes" oNextMonth:bAction := { || FwMsgRun(Nil, {|| fMudaMes(oPanCalend, oCalend, 1 )}, Nil, "Montando calendário...") } //"Montando calendário..." oNextMonth:Align := CONTROL_ALIGN_LEFT Activate MsDialog oDlgTmk Centered Return /* Função que muda de mês */ Static Function fMudaMes(oPan, oCalend, nOp) Local nMonth := oCalend:nMes Local nYear := oCalend:nAno Default nOp := 1 //Se for a seta ->, incrementa um mês If nOp == 1 If nMonth == 12 nMonth := 01 nYear += 1 Else nMonth := nMonth += 1 EndIf //Se for a seta <-, diminui um mês ElseIf nOp == 2 If nMonth == 01 nMonth := 12 nYear -= 1 Else nMonth := nMonth -= 1 EndIf EndIf //Define o calendário e seta o título oCalend:SetCalendar( oPan, cValToChar(nMonth), cValToChar(nYear) ) fMesAno(nMonth, nYear) Return /* Função que define o texto do título em cima do calendário */ Static Function fMesAno(nMonth, nYear) cMesAno := Capital(MesExtenso(nMonth)) + " / " + cValToChar(nYear) cTitHtml := fTitHTML(cMesAno) oMesAtual:SetText( cTitHtml ) //Chama a busca de informações para definir as informações no calendário fBuscaInfo() Return Nil /* Função que transforma o título no formato html */ Static Function fTitHTML(cMesAno) Local cRet := '' cRet += '<p align="center">' cRet += '<font face="' + cFontUti + '" color="#000000" style="font-size:14px"><strong>' + cMesAno + '</strong></font>' cRet += '</p>' Return cRet /* Função que define o primeiro calendário com a fonte Tahom */ Static Function fCalendFont() oCalend:aFontDay[1] := cFontUti oCalend:aFontDayHead[1] := cFontUti oCalend:aFontDayText[1] := cFontUti oCalend:aFontFooter[1] := cFontUti oCalend:aFontFsFer[1] := cFontUti oCalend:aFontHeader[1] := cFontUti oCalend:aFontOff[1] := cFontUti oCalend:aFontToday[1] := cFontUti oCalend:aFontWeek[1] := cFontUti oCalend:cHtmlDay := StrTran(oCalend:cHtmlDay, "MS Sans Serif", cFontUti) oCalend:cHtmlDayOff := StrTran(oCalend:cHtmlDayOff, "MS Sans Serif", cFontUti) oCalend:cHtmlFooter := StrTran(oCalend:cHtmlFooter, "MS Sans Serif", cFontUti) oCalend:cHtmlHeader := StrTran(oCalend:cHtmlHeader, "MS Sans Serif", cFontUti) oCalend:cHtmlToday := StrTran(oCalend:cHtmlToday, "MS Sans Serif", cFontUti) oCalend:cHtmlWeek := StrTran(oCalend:cHtmlWeek, "MS Sans Serif", cFontUti) oCalend:cHtmlWeekend := StrTran(oCalend:cHtmlWeekend, "MS Sans Serif", cFontUti) Return /* Função que busca as informações e atualiza a agenda */ Static Function fBuscaInfo() Local nCell Local nDia For nCell := 1 To (Len(oCalend:aCell) - 10) nDia := oCalend:aCell[nCell][DIA] // Dia //nMes := oCalend:aCell[nCell][MES] // Mês //nAno := oCalend:aCell[nCell][ANO] // Ano //Se for um dia útil If oCalend:aCell[nCell][ATIVO] .And. nDia == 10 aItens := {} aAdd(aItens, "000001 - Cliente A") aAdd(aItens, "000002 - Cliente B") aAdd(aItens, "000003 - Cliente C") //Define as informações da célula oCalend:SetInfo(oCalend:aCell[nCell][ID], aClone(aItens)) EndIf //Se for um dia útil If oCalend:aCell[nCell][ATIVO] //Definindo o nome do dia no calendário dDataAtu := oCalend:aCell[nCell][DATADIA] cObsText := "" cDia := StrZero(Day(dDataAtu), 2) //Se a data não for válida If DataValida(dDataAtu) != dDataAtu //Se for domingo ou sábado, será FDS senão será FERIADO If Dow(dDataAtu) == 1 .Or. Dow(dDataAtu) == 7 cObsText := "FDS" Else cObsText := "FERIADO" EndIf //Define o título da célula cHtml := '<html><p style="color: #ff0000;"><b>' + cDia + ' - ' + cObsText + '</b></p></html>' oCalend:aCell[nCell][OBJETO]:oEditTitle:cTitle := cHtml Else //Define o título da célula cHtml := '<html><p style="color: #0000ff;"><b>' + cDia + '</b></p></html>' oCalend:aCell[nCell][OBJETO]:oEditTitle:cTitle := cHtml EndIf EndIf Next Return /* Função que mostra PopUp, ao clicar com o botão direito */ Static Function fCliqueDir(aInfo, oObj, nRow, nCol) Local cClassName := Upper(Alltrim(oObj:ClassName())) Local oMenu Local oMenuItem := {} Local aOpcoes := {} Local nOpcao := 0 Local dData := aInfo[DATADIA] aInfoDia := aInfo nSelecao := aInfo[OBJETO]:nSelectedIndex cTextoSel := "" nPosCell := aScan(oCalend:aCell, {|x| AllTrim(Upper(x[1])) == aInfo[1]}) //Somente se estiver dentro do ListBox If cClassName == "TLISTBOX" aAdd(aOpcoes, {"Novo Agendamento", {|| fPopOpcao(3, dData)}}) //Se houver linhas, terá outras opções If nSelecao != 0 aAdd(aOpcoes, {"Visualizar Agendamento", {|| fPopOpcao(2, dData)}}) aAdd(aOpcoes, {"Alterar Agendamento", {|| fPopOpcao(4, dData)}}) aAdd(aOpcoes, {"Excluir Agendamento", {|| fPopOpcao(5, dData)}}) cTextoSel := aInfo[OBJETO]:oListBoxContent:aItems[nSelecao] Endif EndIf //Criando o menu e os itens MENU oMenu POPUP For nOpcao := 1 To Len(aOpcoes) aAdd( oMenuItem, MenuAddItem(aOpcoes[nOpcao][1], , , .T., , , , oMenu, aOpcoes[nOpcao][2], , , , , {|| .T.}) ) Next ENDMENU oMenu:Activate(nRow, nCol, oObj) Return Static Function fPopOpcao(nOpcao, dData) Local aPergs := {} Local cTexto := "" Local cEditCli := ".F." Local cCliente := Space(TamSX3('A1_COD')[1]) Local cLoja := Space(TamSX3('A1_LOJA')[1]) Local cObserv := "" Default nOpcao := 3 Default dData := Date() //Define o texto If nOpcao == 3 cEditCli := ".T." cTexto := "Inclusão de Agendamento" Else cEditCli := ".F." If nOpcao == 2 cTexto := "Visualização de Agendamento" ElseIf nOpcao == 4 cTexto := "Alteração de Agendamento" ElseIf nOpcao == 5 cTexto := "Exclusão de Agendamento" EndIf cCliente := SubStr(cTextoSel, 1, 6) cLoja := "01" cTexto += " (" + SubStr(cTextoSel, 10, Len(cTextoSel)) + ")" EndIf //Adiciona os parâmetros aAdd(aPergs, {09, cTexto, 200, 40, .T.}) aAdd(aPergs, {01, "Data", dData, "", ".T.", "", ".F.", 80, .T.}) aAdd(aPergs, {01, "Cliente", cCliente, "", ".T.", "SA1", cEditCli, 80, .T.}) aAdd(aPergs, {01, "Loja", cLoja, "", ".T.", "", cEditCli, 80, .T.}) aAdd(aPergs, {11, "Histórico", cObserv, ".T.", ".T.", .T.}) //Se a pergunta for confirmada If ParamBox(aPergs, "Informe os parâmetros", , , , , , , , , .F., .F.) cCliente := MV_PAR03 cLoja := MV_PAR04 cObserv := MV_PAR05 cNomeCli := Posicione('SA1', 1, FWxFilial('SA1') + cCliente + cLoja, "A1_NOME") //Se for inclusão, adiciona no calendário If nOpcao == 3 aItens := aClone(aInfoDia[OBJETO]:oListBoxContent:aItems) aAdd(aItens, cCliente + " - " + SubStr(cNomeCli, 1, 15)) oCalend:SetInfo(oCalend:aCell[nPosCell][ID], aClone(aItens)) //Se for exclusãoRetira o elemento do array e depois define no calendário ElseIf nOpcao == 5 aItens := aClone(aInfoDia[OBJETO]:oListBoxContent:aItems) aDel(aItens, nSelecao) aSize(aItens, Len(aItens) - 1) oCalend:SetInfo(oCalend:aCell[nPosCell][ID], aClone(aItens)) EndIf EndIf Return
Bom pessoal, por hoje é só.
Abraços e até a próxima