Académique Documents
Professionnel Documents
Culture Documents
org Basic
por Noelson Alves Duarte
Copyright Noelson Alves Duarte permitida a cpia, distribuio e / ou modificao deste documento, sob os termos da GNU Free Documentation License, Version 1.1 ou uma verso posterior publicada pela Free Software Foundation. Uma cpia da licena acompanha este documento.
Verso 2
ndice
1 Macros OpenOffice.org Basic...........................................................................................................5 1.1 Introduo..................................................................................................................................5 1.2 Criando a Primeira Macro.........................................................................................................5 1.3 Executando a Primeira Macro...................................................................................................7 1.4 Compartilhando uma Macro......................................................................................................8 2 Dilogos Personalizados.................................................................................................................11 2.1 Introduo................................................................................................................................11 2.2 Criando um Dilogo ...............................................................................................................11 2.3 Manipulando Eventos do Dilogo...........................................................................................14 3 Pilotos Automticos.........................................................................................................................17 3.1 Introduo................................................................................................................................17 3.2 Criando um Piloto Automtico................................................................................................17 3.3 Manipulando Eventos do Piloto Automtico...........................................................................19 4 Introduo a API do OpenOffice.org..............................................................................................21 4.1 Viso geral...............................................................................................................................21 4.2 Objetos.....................................................................................................................................22 4.3 Definindo objetos.....................................................................................................................24 4.4 Criando um novo documento..................................................................................................26 5 Trabalhando com Documentos........................................................................................................28 5.1 Carregando Documentos.........................................................................................................28 5.2 Salvando Documentos.............................................................................................................30 5.3 Imprimindo Documentos.........................................................................................................31 5.4 Fechando Documentos.............................................................................................................33 5.5 Identificando os Documentos Abertos.....................................................................................34 6 Documentos do Writer....................................................................................................................36 6.1 Introduo................................................................................................................................36 6.2 Editando texto..........................................................................................................................36 6.3 Movendo-se pelo texto.............................................................................................................37 6.4 Formatando texto.....................................................................................................................41 6.5 Formatando com estilo ...........................................................................................................43 6.6 Obtendo o objeto selecionado..................................................................................................47 6.7 Localizando objetos.................................................................................................................48 6.8 Busca e Substituio................................................................................................................50 6.9 Inserindo objetos......................................................................................................................52 6.10 Tabelas...................................................................................................................................53 6.11 Desenhos................................................................................................................................59 7 Documentos do Calc........................................................................................................................63 7.1 Introduo................................................................................................................................63 7.2 Planilhas...................................................................................................................................63 7.3 Editando...................................................................................................................................65 7.4 Navegando pelas Clulas.........................................................................................................67 7.5 Obtendo objetos selecionados..................................................................................................69 7.6 Formatando..............................................................................................................................70 Formatando Pargrafos e Caracteres.......................................................................................70 Mesclando Clulas...................................................................................................................72 Inserindo Bordas......................................................................................................................72
Introduo ao OpenOffice.org Basic 1
Verso 2
Formatao Numrica..............................................................................................................73 Formatao Condicional..........................................................................................................74 7.7 Busca e Substituio................................................................................................................75 7.8 Ordenando................................................................................................................................77 7.9 Filtrando dados........................................................................................................................78 7.10 Inserindo Subtotais................................................................................................................80 7.11 Grficos.................................................................................................................................81 7.12 Seleo durante a execuo da macro...................................................................................85 7.13 Movimentando dados.............................................................................................................88 7.14 Dados de fontes externas.......................................................................................................89 Vnculos...................................................................................................................................89 Importando dados de um banco de dados................................................................................91 8 Banco de Dados...............................................................................................................................93 8.1 Introduo................................................................................................................................93 8.2 Fontes de Dados.......................................................................................................................93 8.3 Conexes..................................................................................................................................97 8.4 Estrutura do Banco de Dados..................................................................................................99 Tabelas.....................................................................................................................................99 Chave Primria.......................................................................................................................104 ndices....................................................................................................................................105 Segurana...............................................................................................................................107 8.5 Registros................................................................................................................................108 Criando um RowSet...............................................................................................................108 Navegando pelos registros.....................................................................................................110 Acessando os dados...............................................................................................................111 Alterando os dados.................................................................................................................112 Obtendo Metadados do RowSet.............................................................................................114 8.6 Consultas...............................................................................................................................114 8.7 Comandos SQL......................................................................................................................117 8.8 Comandos SQL Preparados...................................................................................................119 8.9 Consultas Preparadas.............................................................................................................121 8.10 Vnculos...............................................................................................................................121 9 Apndice Linguagem Basic.......................................................................................................123 9.1 Primeiros Passos....................................................................................................................123 9.2 Elementos do Basic................................................................................................................125 Palavras reservadas................................................................................................................125 Regras para nomes.................................................................................................................125 Comentrios...........................................................................................................................126 Tipos de dados internos.........................................................................................................126 Declarao de variveis.........................................................................................................127 Matrizes..................................................................................................................................127 Escopo das variveis..............................................................................................................128 Constantes simblicas............................................................................................................129 Expresses.............................................................................................................................129 9.3 Fluxo de controle da execuo..............................................................................................132 Comando de deciso If ... Then.............................................................................................132 Comando de deciso Select Case..........................................................................................133 Comando de repetio While ... Wend..................................................................................134 Comando de repetio For ... Next........................................................................................135
2 Introduo ao OpenOffice.org Basic
Verso 2
Comando de repetio Do ... Loop .......................................................................................136 9.4 Organizao do Programa.....................................................................................................137 Comandos...............................................................................................................................137 Sub-rotinas.............................................................................................................................137 Funes..................................................................................................................................138 Passagem de Parmetros........................................................................................................139 Chamada de Procedimentos...................................................................................................139 Modelo Geral de uma Macro.................................................................................................140 10 Mais informaes........................................................................................................................142 10.1 Na rede.................................................................................................................................142 10.2 Com o autor.........................................................................................................................143 10.3 Histrico, alteraes, ...........................................................................................................143 11 Crditos, Agradecimentos, Licena.............................................................................................144 11.1 Crditos................................................................................................................................144 11.2 Agradecimentos ..................................................................................................................144 11.3 Licena.................................................................................................................................144
Verso 2
Apresentao
Este documento o resultado do meu esforo para aprender o OpenOffice.org Basic. Ele est focado, principalmente, nas extenses do OpenOffice.org ao Basic, isto , na API do OpenOffice.org. Assim sendo, as caractersticas bsicas da linguagem de programao Basic no sero abordadas. Se voc j programou ou conhece algum dos sabores Basic e deseja escrever macros para o OpenOffice.org este um bom local para comear. Seno, recomendo procurar algum curso na rede, e se familiarizar com o Basic, antes de se aventurar no OOo Basic. muito importante dominar os fundamentos de uma linguagem de programao. Todos os exemplos de cdigo fonte foram testados com o OpenOffice.org, verso 1.0.1, exceto os pequenos blocos de cdigo fora das sub-rotinas. Para utilizar este texto, o OpenOffice.org deve estar instalado em seu computador. Aps o Captulo 3, recomendo que voc instale, tambm, o Manual de Referncia da API do OpenOffice.org (consulte o captulo Mais Informaes). O Manual de Referncia sofre atualizaes peridicas e sua verso atualizada est disponvel, tambm, para consultas on-line. Espero ter tempo para continuar aprendendo e acrescentando informaes teis aos programadores que, como eu, no dominam a lngua inglesa. Portanto, periodicamente, procure por novas verses deste documento. Como resultado de uma aprendizagem, esta Introduo, seguramente, contm muitos erros e inconsistncias, espero contar com a sua ajuda para corrig-los. Em 20 de junho de 2003
O Autor
Consideraes sobre a verso 2 desta Introduo: A incluso de um captulo sobre Banco de Dados, de um apndice sobre a Linguagem Basic e de novas sees ao longo do texto, praticamente dobrando o nmero de pginas, me convenceu a liberar esta Introduo como uma nova verso. O OpenOffice.org tambm evoluiu, e, na sua nova verso, traz um gravador de macros. Isto amplia as possibilidades de programao para os usurios comuns e, tambm, para todos aqueles que desejam aprender a programar. Porm, acredito que a chave para a programao do OpenOffice.org, est no conhecimento da sua API. Este foi o caminho adotado desde a primeira verso e, dele, no pretendo me afastar.
Verso 2
Em 25 de agosto de 2003
O Autor
Verso 2
1.1 Introduo
Uma macro um programa escrito na linguagem OpenOffice.org Basic com a finalidade de automatizar tarefas do OpenOffice.org. A linguagem OpenOffice.org Basic mantm as principais caractersticas das verses atuais do BASIC, no que diz respeito sintaxe, tipos de dados, operadores, comandos, funes internas e organizao geral do programa. Alm disto, o OpenOffice.org Basic permite o acesso a uma grande quantidade de objetos, com seus mtodos e propriedades, especficos do OpenOffice.org. O OpenOffice.org tem um IDE (Integrated Development Environment - Ambiente de Desenvolvimento Integrado) completo, inclundo: edio de cdigo fonte, verificao de erros, criao de dilogos e gerenciamento de bibliotecas.
Verso 2
Observe a rvore Macro de, no centro do dilogo, temos duas entradas principais soffice e Primeira_Macro.sxw, elas so recipientes (containers) para bibliotecas. Um nvel abaixo, nas duas entradas, temos a biblioteca Standard. Dentro de soffice - Standard temos o mdulo Module1. O recipiente soffice sempre ser carregado com o OpenOffice.org, ele tem bibliotecas globais, usadas em todos os documentos do OpenOffice.org. Observe que alguns mdulos de soffice esto desativados. Cada documento aberto tem seu prprio container com uma biblioteca Standard. Na figura acima, o nico documento aberto Primeira_Macro.sxw. A lista, esquerda do dilogo, exibe os nomes dos procedimentos (Sub-rotinas e funes) do mdulo selecionado. O campo Nome da macro exibe o nome do procedimento selecionado. Ao selecionar o nome de um procedimento, os botes Executar, Atribuir e Editar so ativados. Vamos continuar com a criao da nossa primeira macro: a) Selecione a biblioteca Standard de Primeira_Macro.sxw. b) Clique sobre o boto Novo para criar um novo mdulo. c) Aparece a caixa de entrada Novo Modulo, sugerindo o nome Module1. d) Clique no boto OK para criar o novo mdulo. O IDE Basic carregado. Figura 2: IDE Basic
Verso 2
e) Observe, no editor Basic, a definio de uma sub-rotina Sub Main ... End Sub. Note tambm que a aba Module1 est ativa. f) Digite (ou copie e cole) o cdigo fonte abaixo entre as linhas Sub Main e End Sub.
Dim Dim Dim Dim Dim oDocumento as Object oTexto as Object oCursorVista as Object oCursor as Object sInserir as String
' solicita o texto sInserir = InputBox("Digite o texto:", "Inserir Texto", "") ' testa se algo foi digitado if sInserir = "" then exit sub endif ' obtm o modelo do documento oDocumento = ThisComponent ' obtm o servio Text do documento oTexto = oDocumento.getText() ' obtm a posio do cursor na GUI e cria um cursor de texto oCursorVista = oDocumento.getCurrentController().getViewCursor() oCursor = oTexto.createTextCursorByRange(oCursorVista.getStart()) ' insere o texto na posio corrente do cursor oTexto.insertString(oCursor, sInserir, FALSE)
Verso 2
Pronto, terminamos a nossa primeira macro. Lembre-se que ela est embutida no documento Primeira_Macro.sxw.
Verso 2
tradas para Menus Teclado - Barra de ferramentas e Eventos, onde possvel associar macros a opes de menus, a cones na barra de ferramentas, a uma combinao de teclas e a um evento do OpenOffice.org. Antes de encerrar esta seo, retorne janela do IDE Basic, para simularmos um erro no cdigo fonte: a) Na penltima linha de cdigo oTexto.InsertString(...) - altere o nome da varivel oCursor para oCurso. b) Execute a macro. Surge uma caixa com uma mensagem de erro e um boto OK. Note que a seta de acompanhamento da execuo torna-se vermelha na linha onde ocorre o erro. Aps clicar em OK a execuo da macro finalizada e a linha com o erro permanece selecionada.
c) Corrija o nome da varivel de oCurso para oCursor. Feche o IDE Basic. Salve o documento Primeira_Macro.sxw. No prximo passo, veremos como disponibilizar uma macro para todos os documentos do OpenOffice.org.
Verso 2
c) Selecione, na caixa de listagem Aplicao / Documento, a entrada soffice e pressione o boto Adicionar. d) Um dilogo Abrir Arquivo ser exibido. Localize e selecione o arquivo que contm a macro a ser compartilhada e clique sobre o boto Abrir. e) O dilogo Inserir Bibliotecas ser exibido. Note que as bibliotecas existentes no arquivo esto marcadas para compartilhamento. Desmarque aquelas que no sero compartilhadas e a biblioteca Standard, em seguida, clique sobre o boto Ok.
11
Verso 2
Aps esta operao a biblioteca ser acrescentada ao recipiente soffice. Normalmente, somente as macros da biblioteca Standard so carregadas com o OpenOffice.org. Para carregar uma outra biblioteca, escolha Ferramentas Macro, selecione o recipiente e d um duploclique sobre o nome da biblioteca. Para as bibliotecas Standard, o mtodo de exportar, no funciona adequadamente, pois o recipiente soffice possui a sua prpria biblioteca Standard. Neste caso, devemos usar os recursos de edio do IDE Basic para compartilhar a macro. Ative o IDE Basic e crie um novo mdulo na biblioteca Standard do recipiente soffice. Em seguida, abra o documento com a macro e, no IDE Basic, ative o mdulo que contm a macro a ser compartilhada, selecione toda a macro e copie, alterne para o novo mdulo em soffice / Standard e cole a macro copiada, salve tudo e feche o OpenOffice.org. Agora a sua macro faz parte da biblioteca Standard de soffice e est disponvel para execuo no OpenOffice.org. Se voc pretende desenvolver macros para uso compartilhado, crie bibliotecas prprias para elas, principalmente se usarem dilogos. Para criar uma nova biblioteca, no dilogo Gerenciar (Figura 4), clique sobre o boto Novo, surge o dilogo Nova Biblioteca, na caixa de texto digite um nome para sua biblioteca e clique sobre o boto Ok. O SDK do OpenOffice.org possui a ferramenta pkgchk para empacotamento de macros, o seu uso est fora do escopo desta Introduo. Consulte o Developers Guide para informaes detalhadas.
12
Verso 2
Dilogos Personalizados
2 Dilogos Personalizados
2.1 Introduo
O OpenOffice.org Basic permite a criao de Dilogos Personalizados, atravs de um editor de Dilogos intuitivo e poderoso. Dilogos so uma excelente soluo para interao com o usurio, permitindo que o programador desenhe uma interface grfica consistente para obter ou passar informaes ao operador.
13
Dilogos Personalizados
Verso 2
Figura 6: Editor de Dilogos Vejamos a finalidade de alguns cones existentes no quadro de Controles. Etiqueta usado para colocar etiquetas no dilogo. Boto usado para colocar botes no dilogo. Caixa de texto permite inserir uma caixa de texto num dilogo. Propriedades exibe a janela de propriedades do controle selecionado. Ser ativado quando algum controle for selecionado. Alm da edio das propriedades, permite associar procedimentos (cdigo) a eventos ocorridos no controle. Ativar modo de teste exibe o dilogo como se estivesse em execuo. Inserir Controles num Dilogo uma operao em trs passos: 1) ativar o cone do controle no quadro de controles; 2) definir a rea do dilogo onde o controle ser posicionado. Para isto pressione o boto esquerdo do mouse e arraste formando um retngulo, em seguida, libere o boto do mouse; 3) definir as propriedades do controle.
14
Verso 2
Dilogos Personalizados
Quando um controle adicionado ao dilogo, o OpenOffice.org Basic automaticamente define um valor padro para cada propriedade. Para exibir as propriedades de um controle selecionado, clique sobre o cone Propriedades ou clique duas vezes sobre o controle. Note, tambm, que a janela Propriedades possui uma barra de rolagem para visualizao.
Figura 7: Janela Propriedades Vamos trabalhar em nosso dilogo: a) Selecione o dilogo vazio, clicando na sua borda externa. Note que aparecem marcas em torno do mesmo. Podemos usar estas marcas para redimensionar o nosso dilogo. b) Clique no cone Propriedades para exibir a sua janela, como na figura acima. No campo Ttulo aba Geral digite Inserir Frase e tecle Enter. Clique no boto Subir de Propriedades e observe o ttulo do dilogo. c) Adicione um controle Etiqueta ao dilogo. Para isto, clique no cone Etiqueta, em seguida defina um retngulo na parte superior do dilogo. Defina a sua propriedade ttulo para Digite o texto. d) Coloque uma Caixa de Texto no dilogo, logo abaixo da etiqueta. Observe a sua propriedade Nome: TextField1. No cdigo fonte, nos referimos a um controle pela sua propriedade Nome, da a sua importncia. Note, tambm, que este controle no tem a propriedade Ttulo. e) Vamos colocar dois botes, lado a lado, na parte inferior do dilogo, abaixo da caixa de texto. Defina os seus ttulos para OK e Cancelar.
Introduo ao OpenOffice.org Basic 15
Dilogos Personalizados
Verso 2
f) Ajuste o dilogo e seus controles de modo que fiquem com a aparncia da figura abaixo.
Bem, terminamos o nosso dilogo. Vamos verificar a sua aparncia quando em execuo. Clique sobre o cone Ativar modo de teste no quadro de controles e, aps observar o dilogo, clique em seu cone Fechar para retornar ao editor. Na prxima seo, daremos funcionalidade ao nosso Dilogo.
16
Verso 2
Dilogos Personalizados
oDialogo.execute() End Sub Sub dlgCancelaDialogo oDialogo.endExecute() End Sub Sub dlgInserirFrase Dim oDocumento as Object Dim oTexto as Object Dim oCursorVista as Object Dim oCursor as Object Dim sFrase as String oDialogo.endExecute() ' note a referencia ao controle TextField1 do dialogo sFrase = oDialogo.Model.TextField1.Text if sFrase = "" then exit sub endif ' obtm o modelo do documento oDocumento = ThisComponent ' obtm o servio Text do documento oTexto = oDocumento.getText() ' obtm a posio do cursor na GUI e cria um cursor de texto oCursorVista = oDocumento.getCurrentController().getViewCursor() oCursor = oTexto.createTextCursorByRange(oCursorVista.getStart()) ' insere o texto na posio corrente do cursor oTexto.insertString(oCursor, sFrase, FALSE) End Sub
No cdigo acima, declaramos a varivel oDialogo (Private oDialogo as Variant) fora dos procedimentos, o que a torna visvel em todo o mdulo Module1. Antes de exibir o dilogo, criamos um objeto oDialogo com createUnoDialog() e, para execut-lo, chamamos o seu mtodo execute. Para fechar o dilogo chamamos o seu mtodo endExecute ( chamado em dois procedimentos). Objetos UNO (criados com createUno) devem ser declarados com o tipo Variant e no Object. A seguir, vamos associar os procedimentos aos eventos do dilogo. Selecione a pgina Dialog1 para ativar o editor de dilogos. Em nosso dilogo, selecione o boto OK e clique no cone Propriedades. Surge a janela Propriedades, clique na aba Eventos e, em seguida, clique no boto direita do campo do evento Ao Iniciar. Surge a janela Atribuir macros com o evento Ao Iniciar selecionado. Na rvore Macros, expanda as entradas Primeira_Macro.sxw e Standard, clique sobre Module1. Surge a relao de procedimentos do mdulo, selecione o procedimento dlgInserirFrase e clique sobre o boto Atribuir. Para fechar a janela, clique no boto OK.
Introduo ao OpenOffice.org Basic 17
Dilogos Personalizados
Verso 2
Figura 9: Dilogo Atribuir macro Agora, repita os passos acima para atribuir o procedimento dlgCancelaDialogo ao evento Ao Iniciar, do boto Cancelar do nosso dilogo. Para o OpenOffice.org Basic, o primeiro procedimento no mdulo o ponto de entrada da macro. Logo, a Sub dlgExecutaDialogo ser automaticamente executada toda vez que executarmos a nossa macro. Teste a macro e o dilogo personalizado, clicando sobre o cone Executar, na barra de ferramentas do IDE Basic. Digite uma frase qualquer na caixa de texto do dilogo e clique sobre o boto Ok. Aps a execuo da macro, verifique se a frase foi adicionada corretamente ao documento. No prximo captulo, vamos transformar o nosso dilogo simples num Piloto Automtico.
18
Verso 2
Pilotos Automticos
3 Pilotos Automticos
3.1 Introduo
Um Piloto Automtico um Dilogo exibido em vrios passos. uma forma eficiente de guiar o usurio na execuo de uma tarefa. O OpenOffice.org traz, em sua instalao padro, vrios Pilotos Automticos. Verifique o funcionamento de um deles, selecionando Arquivo Piloto Automtico Carta.
19
Pilotos Automticos
Verso 2
Clique sobre a aba Dialog1, ativando o Editor de Dilogos e redimensione o dilogo tornando-o mais largo. Selecione os botes Ok e Cancelar (clique em Ok, pressione a tecla Shift e clique em Cancelar), mova horizontalmente estes botes para a direita. Na barra de ferramentas do IDE basic, clique no cone Controles e posicione o quadro de controles ao lado do dilogo. Clique no cone Boto, no quadro de controles e adicione dois novos botes no dilogo, lado a lado e esquerda do boto Ok. Selecione o boto CommandButton3, clique no cone Propriedades e defina a propriedade Titulo para << Voltar, altere o valor da propriedade Ativado de Sim para No. Selecione o boto CommandButton4 e defina a sua propriedade Titulo para Prximo >>. Selecione o boto Ok e altere o seu Ttulo para Concluir. Selecione o dilogo (clique na sua borda externa) e defina a sua propriedade Pgina (Step) para 1 (um). Selecione o controle Etiqueta e defina a sua propriedade Pgina para 1 (um). Selecione o controle Caixa de Texto e defina a sua propriedade Pgina para 1 (um). Agora, retoque a primeira pgina do Piloto Automtico, tornando-a semelhante figura abaixo.
Bem, vamos prosseguir em nosso projeto, desenhando a Pgina 2 do Piloto Automtico. Selecione o dilogo e altere a propriedade Pgina para 2 (dois). Note que os controles Etiqueta e Caixa de Texto desaparecem, pois eles pertencem Pgina 1. Os botes, que tm a pgina igual a 0 (zero), continuam visveis.
20
Verso 2
Pilotos Automticos
Adicione uma Etiqueta na parte superior esquerda do dilogo e defina o seu Ttulo para Selecione a posio. Observe que a propriedade pgina igual a 2 (dois), o mesmo valor do dilogo. Clique sobre o cone Boto de Opo, no quadro de controles, e ponha trs botes de opo, na parte superior direita do dilogo, um abaixo do outro. Defina o Ttulo do primeiro boto de opo para no Cursor e a sua propriedade Estado para Selecionado. Defina o Ttulo do segundo boto de opo para no Incio. Defina o Ttulo do terceiro boto de opo para no Final.
Agora, ajuste os controles da segunda pgina do Piloto Automtico, tornando-a semelhante figura abaixo. Note que o boto de opo no Cursor o padro. A ativao e desativao dos botes Voltar e Prximo ser feita em tempo de execuo (pelo cdigo fonte).
Figura 11: Segunda Pgina do Dilogo do Piloto Automtico. Para finalizar o desenho do Piloto Automtico, selecione o dilogo e retorne para a Pgina 1 (um), pois o OpenOffice.org, como padro, exibe a ltima pgina acessada no Editor de Dilogos. Na prxima seo, veremos o cdigo fonte necessrio para dar funcionalidade ao Piloto Automtico.
21
Pilotos Automticos
Verso 2
Sub dlgProximoDialogo oDialogo.Model.Step = 2 oDialogo.Model.CommandButton3.Enabled = true oDialogo.Model.CommandButton4.Enabled = false End Sub Sub dlgVoltarDialogo oDialogo.Model.Step = 1 oDialogo.Model.CommandButton3.Enabled = false oDialogo.Model.CommandButton4.Enabled = true End Sub
Antes de inserir a frase, precisamos verificar a posio, selecionada no segundo passo (botes de opo) e tratar essa escolha adequadamente. Digite o cdigo abaixo na Sub dlgInserirFrase, aps a linha oCursor = oTexto.CreateTextCursorByRange(...) e antes da linha oTexto.insertString(...).
' a posio da frase no incio ou no final if oDialogo.Model.OptionButton2.State = 1 then oCursor.gotoStart(FALSE) elseif oDialogo.Model.OptionButton3.State = 1 then oCursor.gotoEnd(FALSE) endif
Agora, vamos ligar os procedimentos aos eventos que nos interessam. Alterne para o editor de dilogos. Selecione o boto Voltar e clique no cone Propriedades. Surge a janela Propriedades, clique na aba Eventos e, em seguida, clique no boto direita do campo do evento Ao Iniciar. Surge a janela Atribuir macros com o evento Ao Iniciar selecionado. Na rvore Macros, expanda as entradas Primeira_Macro.sxw e Standard, clique sobre Module1. Surge a relao de procedimentos do mdulo, selecione o procedimento dlgVoltarDialogo e clique sobre o boto Atribuir. Para fechar a janela, clique no boto OK. Seguindo os passos acima, atribua o procedimento dlgProximoDialogo ao evento Ao Iniciar do boto Prximo. Execute a macro e verifique se tudo ocorreu como o esperado. Agora, voc pode se aventurar escrevendo suas prprias macros. Como um ponto de partida, consulte o prximo captulo em busca de informaes complementares.
22
Verso 2
Normalmente, um mdulo pode conter servios, interfaces, estruturas, enumeraes, definies de tipo e grupos de constantes. Por exemplo, entre os componentes encontrados no mdulo beans, temos: Services - relao de servios do mdulo Interfaces - relao de interfaces do mdulo Structs - relao de est ruturas do mdulo Exceptions - relao de excees do mdulo Enums - relao de enumeraes do mdulo Constant Groups - relao de grupos de constantes do mdulo Um mdulo no precisa conter todos estes elementos. Simplificando bastante, podemos dizer que: Um servio (Service), normalmente, representa um objeto. Uma interface (Interface) contm as definies dos mtodos referentes a um dado objeto. Uma estrutura (Struct) um tipo de dado contendo um ou mais campos. Uma exceo (Exception) um indicador de erro passado ao sistema em tempo de execuo. Uma enumerao (Enum) contm uma relao de constantes inteiras. Um grupo de constantes (Constant Group) define valores para determinadas constantes.
23
Verso 2
Servios (Services), na API do OpenOffice.org, correspondem a objetos. Um servio pode incluir outros servios, oferecer interfaces e ter propriedades. No tpico sobre objetos, apresentaremos os servios com mais detalhes. As estruturas so tipos de dados contendo campos, do mesmo tipo ou no, agrupados sob um mesmo nome. Como exemplo, vamos estudar a estrutura < com.sun.star.awt.Size >, utilizada por diversos servios da API. Ela define o tamanho de um objeto e contm dois campos: Struct < com.sun.star.awt.Size > Width - valor do tipo longo (Long), especificando a largura Height - valor do tipo longo (Long), especificando a altura Uma estrutura pode incluir outras estruturas ou objetos como campos. Podemos declarar uma varivel simples ou um vetor do tipo estrutura, como abaixo: Dim vTamanho As New com.sun.star.awt.Size ' declara uma varivel simples Dim vetorTam (2) As New com.sun.star.awt.Size ' declara um vetor para 3 elementos Dim vTam ( ) As New com.sun.star.awt.Size ' declara um vetor vazio O comando As New utilizado em declaraes de tipos de dados no suportado internamente pelo Basic. Note, ainda, a especificao completa do tipo de dado. O acesso aos campos da estrutura se d atravs do operador ponto ( . ) como em: ' define os valores dos campos da estrutura Size vTamanho vTamanho.Width = 2000 vTamanho.Height = 1000 ' ou, ainda nAltura = vTamanho.Height ' acesso aos campos de um vetor de estrutura vetorTam(0).Width = 5000 vetorTam(0).Height = 2500 Uma enumerao contm uma relao de constantes com valores inteiros consecutivos. Por exemplo, a enumerao < com.sun.star.awt.PushButtonType > define tipos possveis para um boto, so eles: STANDARD - comporta-se como um boto padro OK - comporta-se como um boto Ok CANCEL - comporta-se como um boto Cancelar HELP - comporta-se como um boto Ajuda Normalmente, os valores de uma enumerao so utilizados como propriedades de objetos, como abaixo: oBotao1.PushButtonType = com.sun.star.awt.PushButtonType.STANDARD
24
Verso 2
PushButtonType uma propriedade do objeto boto. Devemos fornecer a especificao completa para o nome da constante. Um grupo de constantes tambm contm valores para constantes relacionadas, contudo eles no so, necessariamente, consecutivos. A atribuio das constantes de um grupo a uma varivel segue o mesmo padro das enumeraes.
4.2 Objetos
J dissemos que um servio uma especificao de um objeto, que engloba um conjunto de interfaces e propriedades. Uma interface uma coleo de mtodos. Uma propriedade um valor que determina uma caracterstica de um servio. De uma maneira errnea, um objeto como uma estrutura que, alm dos campos comuns, pudesse conter campos especiais definindo procedimentos. Os campos comuns seriam as propriedades e os especiais os mtodos. Se voc quiser descobrir o porqu da palavra errnea, procure algum texto introdutrio sobre programao orientada a objetos. Vamos analisar o servio Spreadsheet, do mdulo < com.sun.star.sheet >, que representa uma Planilha num documento do Calc, para fixar os conceitos. < com.sun.star.sheet.Spreadsheet >: Inclui o servio: < com.sun.star.sheet.SheetCellRange > Exporta diversas interfaces, entre elas: < com.sun.star.sheet.XSpreadsheet > < com.sun.star.container.XNamed > Possui as propriedades: IsVisible - As Boolean PageStyle - As String Uma interface o local aonde os mtodos dos objetos so definidos. No exemplo acima, a interface XSpreadsheet define mtodos que criam um cursor para uma extenso de clulas, so eles: createCursor - cria um cursor para toda a planilha createCursorByRange - cria um cursor para uma extenso de clulas Um mtodo corresponde a um procedimento da linguagem Basic. Existe outra caracterstica das interfaces que deve ser citada. Uma interface pode ser derivada a partir de outra (superinterface). Neste caso, ela herda os mtodos da superinterface. Como exemplo, vejamos a hierarquia da interface XSpreadsheet: com.sun.star.uno.XInterface
Introduo ao OpenOffice.org Basic 25
Verso 2
|___ com.sun.star.table.XCellRange |___ com.sun.star.sheet.XSheetCellRange |___ com.sun.star.sheet.XSpreadsheet Note que XSpreadsheet definida a partir da interface XSheetCellRange, que por sua vez derivada de XCellRange. A conseqncia prtica disto : todos os objetos que oferecem XSpreadsheet suportam os mtodos de XCellRange e XSheetCellRange. Uma propriedade define uma caracterstica de um objeto. Por exemplo, a propriedade IsVisible, acima, determina se a planilha a que se refere ser ou no visvel na interface grfica. Observe que Spreadsheet inclui o servio SheetCellRange, isto significa que os mtodos das suas interfaces e, tambm, as suas propriedades so suportadas por Spreadsheet. J vimos que o acesso aos campos de uma estrutura se d atravs do operador ponto ( . ), isto tambm se aplica aos mtodos e propriedades de um objeto. Ento, supondo que temos uma varivel oPlanilha1, do tipo objeto Spreadsheet, podemos escrever: oCursor = oPlanilha1.createCursor ( ) ' cria um cursor abrangendo toda a planilha bVisivel = oPlanilha1.IsVisible ' atribui a bVisivel o valor da propriedade IsVisible Devemos lembrar que um mtodo pode ou no retornar um valor. No primeiro caso eles se assemelham s funes e, no segundo, s sub-rotinas do Basic. Existem propriedades que so representadas por estruturas. Uma das mais utilizadas na API do OpenOffice.org a estrutura < com.sun.star.beans.PropertyValue >, com quatro campos, entre os quais o par: Name Value - cadeia com o nome da propriedade ( sensvel a maisculas / minsculas ). - tipo de dado Variant com o valor da propriedade.
O servio MediaDescriptor, que contm muitas propriedades referentes a abertura e gravao de documentos, pode ser representado por um vetor da estrutura PropertyValue.
26
Verso 2
O parmetro da funo a especificao completa para o servio. Todos os servios iniciam com com.sun.star, em seguida vem o nome do mdulo, neste caso, frame e, por fim, o nome do servio Desktop. Note, tambm, que a especificao passada como uma cadeia. Aps a chamada, podemos verificar se o servio foi criado com:
If isNull( oDesktop ) Then ' Erro na criao do servio End If
Existem servios que podem ser criados atravs de chamadas a mtodos da API. Por exemplo, um documento do Writer pode conter objetos como texto e desenhos. Os servios que representam estes objetos podem ser criados de duas maneiras: Na primeira, usamos um mtodo exclusivo para esta finalidade: oObjetoTexto = oDocumento.getText ( ) O mtodo getText, retorna um objeto com o contedo texto de um documento do Writer. Na segunda, podemos chamar um dos mtodos do gerente de servios: oObjetoLinha = oDocumento.createInstance ( com.sun.star.drawing.LineShape) O mtodo createInstance cria o objeto (servio) especificado como parmetro. Um servio (objeto) pode, tambm, ser parte das propriedades de um outro objeto. Neste caso, ele ser obtido como o resultado de uma chamada ao mtodo getPropertyValue ( ): oPropriedade = oObjeto.getPropertyValue ( Nome_da_Propriedade) O mtodo getPropertyValue retorna um objeto, se o valor da propriedade for um objeto. Diversos servios so dependentes de um contexto. Por exemplo, voc no pode criar uma clula fora de uma planilha. Outros servios no precisam de um ambiente para operar. Existem, ainda, servios que no oferecem nenhuma interface, servindo unicamente para obter e definir propriedades. O Basic oferece duas propriedades que facilitam o acesso a servios, so elas: StarDesktop equivalente ao objeto retornado por uma chamada funo createUnoService( com.sun.star.frame.Desktop ). Digite o cdigo abaixo numa nova sub-rotina, execute e observe o resultado:
MsgBox StarDesktop.Dbg_SupportedInterfaces ' ' o mesmo que: ' Dim oDesktop oDesktop = CreateUnoService( "com.sun.star.frame.Desktop" ) MsgBox oDesktop.Dbg_SupportedInterfaces
27
Verso 2
ThisComponent retorna o objeto documento que contm o cdigo Basic, existe apenas em documentos do Writer, Calc, Impress ou Draw. Algumas de suas interfaces dependem do tipo de documento.
Dim oDocumento As Object oDocumento = ThisComponent
O OOo Basic tem trs propriedades muito teis para a inspeo de objetos, so elas: Dbg_SupportedInterfaces retorna as interfaces suportadas pelo objeto Dbg_Properties retorna as propriedades do objeto Dbg_Methods retorna os mtodos suportados pelo objeto Para obter estas propriedades, use a forma Objeto.Propriedade. Por exemplo, verifique as interfaces suportadas pelo modelo de documento, executando o cdigo abaixo:
Sub Main MsgBox ThisComponent.Dbg_SupportedInterfaces End Sub
A interface com.sun.star.lang.XServiceInfo possui os mtodos abaixo, teis para inspeo de servios: getImplementationName ( ) As String retorna o nome de implementao do servio supportsService (sNome As String ) As Boolean retorna True se o servio sNome for suportado getSupportedServiceNames ( ) As String () retorna um conjunto de cadeias com os nomes dos servios suportados, inclusive os indiretos Vamos usar as facilidades de inspeo de objetos, oferecidas pelo OpenOffice.org Basic, para verificar o servio Spreadsheet. Num documento do Calc, crie a macro abaixo e execute-a observando a sada:
Sub servicoSpreadsheet ' exibe info do servio Spreadsheet oDocumento = ThisComponent oSheet = oDocumento.Sheets(0)
28
Verso 2
' servios suportados sServ = oSheet.getSupportedServiceNames() sMsg = "" For i = 0 To UBound(sServ()) sMsg = sMsg + sServ(i) + Chr$(10) Next i MsgBox sMsg ' interfaces suportadas MsgBox oSheet.Dbg_SupportedInterfaces ' mtodos MsgBox oSheet.Dbg_Methods ' propriedades MsgBox oSheet.Dbg_Properties End Sub
Durante a execuo, sero exibidos os servios, interfaces, mtodos e propriedades suportadas pelo objeto Spreadsheet. Na prxima seo, vamos apresentar um exemplo, que utiliza diversos conceitos apresentados neste captulo.
29
Verso 2
As linhas iniciadas pelo comando Dim declaram todas as variveis usadas pela sub-rotina. Para carregar um arquivo, usamos o mtodo loadComponentFromURL(), que definido por uma interface (XComponentLoader) do servio Desktop. Ento, precisamos de um objeto UNO Desktop, declarado na linha Dim oDesktop As Variant. Aqui, o tipo Variant segue uma recomendao do Developers Guide para a declarao de objetos UNO. A varivel sUrl (tipo String) recebe a especificao completa do caminho para o arquivo. Ser passada como parmetro do mtodo loadComponentFromURL(). O mtodo loadComponentFromURL() retorna um objeto Document. A linha Dim oDocumento As Object reserva memria para este objeto. O mtodo loadComponentFromURL(), recebe uma sequncia de propriedades como parmetro. A linha Dim mPropArquivo declara e define um vetor para esta sequncia. A definio do objeto feita com o operador New seguido do tipo de objeto (As New com.sun.star.beans.PropertyValue). A linha oDesktop = createUnoService(...) se encarrega da criao do objeto Desktop. A linha oDocumento = oDesktop.loadComponentFromURL(...) carrega o documento de acordo com os parmetros e retorna um objeto do tipo Document. Note que a sequncia mPropArquivo passada como argumento seguida de (). O parmetro _blank significa que um novo quadro ser criado para o documento. Pronto, agora digite (ou copie e cole) a Sub criaNovoDocumento, alterando a varivel sUrl para conter um caminho completo do seu sistema, e execute a macro para ver seu resultado. No prximo captulo, aprenderemos mais sobre programao com documentos do OpenOffice.org.
30
Verso 2
b) Definir a URL Voc deve fornecer uma cadeia de caracteres com a especificao completa do caminho do documento, caso esteja abrindo um documento existente, na forma: file:///caminho_completo_do_arquivo Para novos documentos, criados a partir do modelo padro, existem URLs pr-definidas, que devem ser usadas de acordo com o tipo de documento: URL private:factory/swriter private:factory/scalc private:factory/sdraw private:factory/simpress Descrio Cria um novo documento do Writer Cria um novo documento do Calc Cria um novo documento do Draw Cria um novo documento do Impress
c) Definir as propriedades do descritor de mdia O descritor de mdia um servio (com.sun.star.document.MediaDescriptor) que define como um recurso deve ser carregado. As propriedades do descritor so definidas numa sequncia com.sun.star.beans.PropertyValue. Declare um vetor para a sequncia, de acordo com o nmero de propriedades a alterar, como abaixo:
' declara um vetor vazio, para efeito de passagem como parmetro Dim mPadrao() ' define um vetor para 1 propriedade (ndice 0) Dim mPropArquivo(0) As New com.sun.star.beans.PropertyValue mPropArquivo(0).Name = "AsTemplate" mPropArquivo(0).Value = True ' define um vetor para 2 propriedades (ndices 0 e 1) Dim mPropriedades(1) As New com.sun.star.beans.PropertyValue
31
Verso 2
Seguem as descries de algumas propriedades (existem vrias): Propriedade AsTemplate Tipo Descrio Boolean Se True cria um novo documento, a partir do documento carregado, mesmo que ele no seja um modelo. Se for um modelo e AsTemplate for False o documento ser carregado para edio. String String Define um filtro a ser usado para carregar ou salvar o documento. Aps a carga, salta para uma posio (clula, bookmark, etc).
Boolean Se True, o documento no ser exibido na interface grfica Boolean Sobrescreve um documento ao salvar. Padro True. Boolean Se o documento deve ser somente leitura ou leitura / gravao. Boolean Na gravao o documento no ser compactado (zip). String Senha para gravar ou carregar o documento.
d) Definir o quadro de destino o frame onde o documento ser carregado / criado, se j existir um quadro com o nome especificado, ele ser usado, seno um novo ser criado. Os nomes pr-definidos, a seguir, nunca devem ser usados como nome de quadros: _blank; _default; _self; _parent; _top e _beamer. Use _blank para criar um novo quadro. e) Definir o flag de busca uma constante que define o tipo de algoritmo usado para encontrar o quadro de destino. Use um valor 0 para desconsiderar. f) Chamar o mtodo loadComponentFromURL() Este mtodo, do objeto Desktop, carrega o componente definido pela URL, dentro do quadro de destino. Vejamos seus detalhes: loadComponentFromURL( URL As String, FrameDestino As String, FlagBusca As Long,
32 Introduo ao OpenOffice.org Basic
Verso 2
Propriedades () As <com.sun.star.beans.PropertyValue> ) O valor de retorno um objeto XComponent ou Null em caso de erro. Eis um exemplo de chamada:
oDocumento = oDesktop.loadComponentFromURL(sUrl, "_blank", _ 0, mPropArquivo())
33
Verso 2
Documentos abertos com loadComponentFromURL ( ), devem usar os mtodos storeAsURL ou storeToURL. Como exemplo, digite (ou copie e cole) o cdigo fonte abaixo, aps a linha ' INSERIR CDIGO PARA SALVAR AQUI da Sub criaNovoDocumento ( ), edite a varivel sUrl conforme o seu sistema, execute a macro e verifique que um novo arquivo foi gravado em sURL..
' -------------------' Grava o novo arquivo ' -------------------' Define a URL do novo arquivo (ALTERE para seu sistema) sUrl = "file:///D:/nad/openoffice/novo_texto.sxw" ' define a propriedade Overwrite para False mPropArquivo(0).Name = "Overwrite" mPropArquivo(0).Value = FALSE ' grava o novo documento oDocumento.storeAsURL(sUrl, mPropArquivo())
Temos, ainda, os mtodos abaixo, relacionados com a tarefa de salvar arquivos: isModified() As Boolean Retorna True se o recurso foi modificado, seno retorna False. hasLocation ( ) As Boolean Retorna True se o arquivo j existe (foi gravado), seno retorna False. GetLocation ( ) As String Retorna uma String com a URL do recurso. isReadonly ( ) As Boolean Retorna True se for somente leitura, em caso contrrio retorna False A seguir, temos um fragmento de cdigo mais elaborado para salvar arquivos:
If (oDocumento.isModified) Then If (oDocumento.hasLocation And (Not oDocumento.isReadOnly)) Then oDocumento.store() Else oDocumento.storeAsURL(sURL, mPropArquivo()) End If End If
34
Verso 2
Contm a orientao do papel Especifica um tamanho de papel padro ou definido pelo usurio Especifica o tamanho do papel em 1/100 mm True se a impressora estiver ocupada; False seno
CanSetPaperOrientation True se a impressora permite mudar a orientao do papel CanSetPaperFormat CanSetPaperSize True se a impressora permite mudar o formato do papel True se a impressora permite mudar o tamanho do papel
As quatro ltimas propriedades so somente leitura. Vejamos um exemplo que acessa as propriedades da impressora corrente:
Sub obtemDescritorImpressora Dim oDoc As Object Dim oDescImpr As Variant Dim sMsg As String oDoc = ThisComponent ' obtem o vetor de estruturas PrinterDescriptor oDescImpr = oDoc.getPrinter() ' obtem tamanho do vetor de estruturas
35
Verso 2
iNrEstruturas% = UBound(oDescImpr) ' extrai os nomes das propriedades da impressora For n = 0 To iNrEstruturas% sMsg=sMsg + oDescImpr(n).Name + " " Next n ' exibe os nomes das propriedades MsgBox sMsg,0,"Propriedades Impressora" ' obtem e exibe o valor da propriedade PageFormat ' A3=0; A4=1; Letter/Carta=5; ... MsgBox oDescImpr(2).Value ' verifica se PageFormat pode ser alterada If oDescImpr(6).Value Then MsgBox "Formato da Pgina, pode ser alterado!" ' ento altera para A4 oDescImpr(2).Value = 1 Else MsgBox "Formato da Pgina, no pode ser alterado!" End If ' exibe o valor de PageFormat novamente MsgBox oDescImpr(2).Value End Sub
O cdigo acima chama o mtodo getPrinter ( ) para obter as propriedades da impressora corrente. Em seguida, no lao For ... Next, extrai os nomes de cada propriedade. E, mais abaixo, obtm e altera o formato da pgina, se possvel.
setPrinter ( aImpressora As Variant < com::sun::star::beans::PropertyValue >) Atribui uma nova impressora ao documento. Pode implicar numa reformatao. As propriedades da impressora so as mesmas da tabela acima.
print ( xOpcoes As Variant < com::sun::star::beans::PropertyValue >) Imprime o documento de acordo com as opes de impresso (PrintOptions) em xOpcoes. Estas opes so descritas na tabela a seguir: Opo CopyCount FileName Collate Descrio ( Int ) Especifica o nmero de cpias a imprimir Cadeia com o nome de um arquivo para a impresso Se True todo o documento ser impresso antes da prxima cpia, seno imprime todas as cpias pgina a pgina Uma cadeia com as pginas a serem impressas, por exemplo: 1;3;5-8;12
Pages
36
Verso 2
' imprimir o documento com as definies correntes Dim aOpcoes () oDocumento.print (aOpcoes() )
Para imprimir numa impressora que no a padro, voc precisa alterar a propriedade Name da impressora e chamar setPrinter definindo uma nova impressora, como abaixo:
Dim mImpressora(0) As New com.sun.star.beans.PropertyValue Dim aOpcoes() ' somente para passar o parmetro ' mImpressora(0).Name="Name" mImpressora(0).value="Segunda_Impressora" ' define a nova impressora para o objeto, ' pode ocorrer uma formatao do documento oDocumento.setPrinter = mImpressora() ' imprime com as opcoes padro oDocumento.print( aOpcoes() )
Acrescente a linha acima aps a ltima linha da Sub criaNovoDocumento(), execute a macro e observe o resultado. b) Aberto pela interface do OpenOffice.org Se o documento foi carregado com o comando Arquivo Abrir do OpenOffice.org e no houve a definio de um objeto Document, use a propriedade ThisComponent, como abaixo:
ThisComponent.dispose()
37
Verso 2
Cuidado, o mtodo dispose() descarta todas as alteraes efetuadas no documento. Portanto, antes de cham-lo, certifique-se de grav-las. Ou, ainda, use isModified() para alertar o usurio. Existem maneiras mais seguras para controlar o fechamento de componentes, porm esto alm do escopo desta Introduo.
Analise atentamente o cdigo fonte acima, ele demonstra aspectos importantes da programao da API do OpenOffice.org. Note como se d a criao de uma enumerao e como visitamos os seus elementos.
38
Verso 2
Aps a identificao de um documento, voc pode, por exemplo, comandar a sua impresso ou o seu fechamento, alm, claro, de poder manipular o seu contedo, aplicando as tcnicas que sero vistas nos prximos captulos.
39
Documentos do Writer
Verso 2
6 Documentos do Writer
6.1 Introduo
Neste captulo, veremos como efetuar tarefas simples de processamento de texto, como: edio, formatao, busca e substituio. Vamos abordar o assunto atravs de exemplos prticos, com uma breve explicao dos aspectos mais importantes. Um documento do Writer contm principalmente texto, organizado em pargrafos e tabelas. Alm destes elementos bsicos, ele suporta molduras, objetos embutidos, campos, grficos, marcadores, ndices e muitos outros objetos. Estes dados compreendem um modelo de documento. Atravs do modelo, podemos manipular os dados independentemente da sua representao visual. Para lidar com o aspecto visual do documento, o modelo dispe de um objeto controlador. Alguns elementos de um documento (grficos, molduras, etc) so nomeados e esto ancorados num pargrafo, caractere ou pgina. Os pargrafos no recebem um nome e nem um ndice, de modo que seu acesso deve ser sequncial.
40
Verso 2
Documentos do Writer
oTxt = oDoc.getText() sStr = "Esta uma " oTxt.setString( sStr ) oTxtRange = oTxt.getEnd() sStr = "cadeia de caracteres " oTxtRange.setString( sStr ) End Sub
Neste exemplo, usamos a interface XTextRange para editar texto. Eis os seus mtodos: getText() As Text retorna um objeto Text getString() As String retorna a String contida no objeto setString( sStr As String) define a String como o contedo do objeto getStart() As Object <TextRange > retorna um objeto TextRange apontando para o incio do objeto chamador getEnd() As Object <TextRange> retorna um objeto TextRange apontando para o final do objeto chamador Inicialmente, chamamos o mtodo getText ( ), que retorna um objeto Text, este passo corresponde ao item b) acima. Em seguida, na linha oTxt.setString(sStr), definimos uma cadeia de caracteres para o nosso objeto Text, isto significa que todo o contedo do documento objeto oTxt - ser substitudo pela cadeia sStr de setString. Antes de inserir mais texto, precisamos obter o final do contedo de oTxt com a chamada ao mtodo getEnd( ) e usar este novo objeto TextRange para inserir mais texto. Atravs do mtodo getStart, poderamos inserir texto no incio. Note, ainda, que as variveis dos servios Text e TextRange so declaradas como Object. Ateno, oTxt tambm um TextRange, assim podemos substituir a varivel oTxtRange pelo encadeamento de mtodos abaixo: oTxt.getEnd ().setString ( sStr ) Este processo de edio muito limitado. Podemos apenas substituir todo o contedo do texto e inserir texto no incio ou no final do documento.
41
Documentos do Writer
Verso 2
42
Verso 2
Documentos do Writer
gotoRange (xRange As <TextRange>, bExpande As Boolean) move ou expande o cursor sobre o objeto TextRange Em todos os mtodos acima, se bExpande for True o alcance do cursor ser expandido. b) Mtodos para controlar o estado do cursor: collapseToStart ( ) move a posio do final do cursor para o seu incio collapseToEnd ( ) move a posio do incio do cursor para o seu final isCollapsed ( ) As Boolean retorna True se as posies inicial e final do cursor forem iguais As interfaces XWordCursor, XSentenceCursor e XparagraphCursor, todas derivadas de XTextCursor, tambm fornecem mtodos para controle e movimento do cursor. a) Mtodos de XWordCursor: gotoNextWord (bExpande As Boolean) As Boolean gotoPreviousWord (bExpande As Boolean) As Boolean gotoEndOfWord (bExpande As Boolean) As Boolean gotoStartOfWord (bExpande As Boolean) As Boolean isStartOfWord ( ) As Boolean isEndOfWord ( ) As Boolean b) Mtodos de XSentenceCursor: gotoNextSentence (Expande As Boolean) As Boolean gotoPreviousSentence (bExpande As Boolean) As Boolean gotoStartOfSentence (bExpande As Boolean) As Boolean gotoEndOfSentence (bExpande As Boolean) As Boolean isStartOfSentence ( ) As Boolean isEndOfSentence ( ) As Boolean c) Mtodos de XParagraphCursor: gotoStartOfParagraph (bExpande As Boolean) As Boolean gotoEndOfParagraph (bExpande As Boolean) As Boolean gotoNextParagraph (bExpande As Boolean) As Boolean gotoPreviousParagraph (bExpande As Boolean) As Boolean isStartOfParagraph ( ) As Boolean isEndOfParagraph ( ) As Boolean
43
Documentos do Writer
Verso 2
Antes de apresentar um exemplo, vejamos os caracteres de controle que podem ser inseridos num documento do Writer. Na interface grfica, eles so chamados de caracteres no imprimveis e tm funes especiais na apresentao final do documento. Para facilitar o seu emprego, estes caracteres esto definidos como constantes, no grupo de constantes com.sun.star.text.ControlCharacter. Eles podem ser inseridos no texto com o mtodo insertControlCharacter () ou como parte do contedo de uma cadeia, neste caso, usando o seu cdigo Unicode. Eis uma relao dos caracteres de controle com os seus respectivos cdigos:
PARAGRAPH_BREAK Insere uma quebra de pargrafo LINE_BREAK HARD_HYPHEN SOFT_HYPHEN HARD_SPACE Quebra de linha dentro de um pargrafo Caractere que aparece Hifenizao no remove. Espao com tamanho fixo. como um 0x000D 0x000A travesso. 0x2011 0x00AD 0x00A0 No tem
Vamos encerrar esta seo com um exemplo demonstrando o emprego de alguns dos conceitos e mtodos apresentados. Ative o IDE Basic, digite (ou copie e cole) o cdigo fonte a seguir e execute a sub-rotina Sub processaTexto. Ela insere texto, caracteres de controle e uma quebra de pgina num novo documento sem nome. Depois, seleciona e substitui duas palavras por uma cadeia vazia.
Sub processaTexto Dim oDesktop As Variant Dim oDoc As Object Dim oCursor As Object Dim oTexto As Object Dim mPropArquivo() Dim sStr As String oDesktop = createUnoService("com.sun.star.frame.Desktop") oDoc = oDesktop.loadComponentFromURL("private:factory/swriter",_ "_blank", 0, mPropArquivo()) oTexto = oDoc.getText() oCursor = oTexto.createTextCursor() sStr = "Este o texto do primeiro pargrafo do documento" With oTexto ' insere o texto na posio corrente do cursor .insertString(oCursor, sStr, False) ' insere um pargrafo .insertControlCharacter(oCursor,_ com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False) .insertString(oCursor, "Este o segundo pargrafo ", False) .insertControlCharacter(oCursor, _ com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)
44
Verso 2
Documentos do Writer
End With ' insere uma nova pgina oCursor.gotoStartOfParagraph(True) oCursor.breakType = com.sun.star.style.BreakType.PAGE_BEFORE oTexto.insertString(oCursor, "Estou numa nova pgina.", False) ' move o cursor sem expanso oCursor.gotoStart(False) oCursor.gotoNextWord(False) oCursor.gotoNextWord(False) oCursor.gotoNextWord(False) ' move o cursor expandindo, i., seleciona texto do oCursor.gotoNextWord(True) oCursor.gotoNextWord(True) ' substitui o texto entre o incio e o final do cursor oTexto.insertString(oCursor, "", True) End Sub
No cdigo acima, estude o emprego do parmetro bExpande (True ou False) ele muito importante. Outro aspecto a insero da quebra de pgina. No existe um caractere de controle para quebra de pgina ou coluna. Ela uma propriedade do pargrafo. Note que usamos oCursor para definir uma propriedade do pargrafo (oCursor.breakType). Isto possvel porque o objeto TextCursor herda caractersticas de TextRange. Os valores possveis para a propriedade breakType (quebra de pgina e coluna) esto enumerados em com.sun.star.style.BreakType, aqui usamos PAGE_BEFORE. Finalmente, observe, no novo documento, que o cursor da vista encontra-se no final do mesmo, apesar da ltima ao (seleo e substituio) ter ocorrido no primeiro pargrafo, o que demonstra a independncia entre o cursor de texto e a interface grfica. Lembre-se, ainda, que o acesso interface grfica se d atravs do controlador do modelo do documento. O cdigo fonte da sub-rotina dlgInserirFrase, do Captulo 3 (Piloto Automtico), mostra como acessar o controlador e criar um cursor da vista.
Documentos do Writer
Verso 2
O servio com.sun.star.style.CharacterProperties define as propriedades comuns de caracteres. Eis algumas delas: Propriedade CharFontName CharFontStyleNa me CharFontFamily CharHeight CharUnderline CharWeight CharPosture CharFlash CharStrikeout CharRotation Descrio Especifica o nome do estilo da fonte Contm o nome do estilo da fonte Contm a famlia da (com.sun.star.awt.FontFamily) Contm o valor do caractere (com.sun.star.awt.Underline) Contm o valor do (com.sun.star.awt.FontWeight) Contm o valor da (com.sun.star.awt.FontSlant) peso postura fonte conforme
Se True o caractere pisca. opcional Define o tipo de risco (com.sun.star.awt.FontStrikeout) Define a rotao do caractere em graus do caractere
Na tabela acima, as referncias ao mdulo com.sun.star.awt, contm possveis valores para as respectivas propriedades dos caracteres. O servio com.sun.star.style.ParagraphProperties define as propriedades dos pargrafos. A tabela abaixo apresenta algumas: Propriedade ParaAdjust ParaBackColor Descrio Define o tipo (com.sun.star.style.ParagraphAdjust) Contm a cor de fundo, opcional de ajuste
ParaLastLineAdju Define o ajuste da ltima linha st ParaLeftMargin ParaRightMargin ParaTopMargin Define a margem esquerda em 1/100 mm ( As Long ) Define a margem direita em 1/100 mm ( As Long ) Define a margem superior do pargrafo em 1/100 mm (As Long)
46
Verso 2
Documentos do Writer
Contm o nome do estilo de pargrafo corrente, opcional. Define a borda esquerda, (com.sun.star.table.BorderLine ) Define a borda direita, (com.sun.star.table.BorderLine ) Define a borda superior, (com.sun.star.table.BorderLine ) Define a borda inferior, (com.sun.star.table.BorderLine ) opcional opcional opcional opcional
ParaFirstLineInde Valor longo com a identao da primeira linha, opcional nt ParaVertAlignme nt Define o alinhamento (com.sun.star.text.ParagraphVertAlign) vertical
Novamente, as referncias com.sun.star contm valores possveis para as respectivas propriedades, geralmente um valor de 0 a N para constantes. Veja a seguir algumas delas. Constantes de com.sun.star.style.ParagraphAdjust: LEFT, RIGHT, BLOCK, CENTER e STRETCH. Constantes de com.sun.star.text.ParagraphVertAlign: AUTOMATIC, BASELINE, TOP, CENTER e BOTTOM. Existem muitas outras propriedades para caracteres e pargrafos, uma consulta ao Developers Guide e ao Reference Manual, ambos da Sun Microsystems Inc, indispensvel para aqueles que desejam programar para o OpenOffice.org. Vamos retomar o nosso ltimo exemplo a Sub processaTexto. Desejamos mudar a inclinao e cor da fonte da palavra segundo e, tambm, o estilo de um pargrafo de Padro para Ttulo. Digite o cdigo abaixo, aps a ltima linha da sub-rotina, execute-a e observe o resultado.
' ---------------------' cdigo para formatao ' ---------------------oCursor.gotoNextParagraph(FALSE) oCursor.gotoNextWord(False) oCursor.gotoNextWord(False) oCursor.gotoNextWord(False) oCursor.gotoNextWord(True) oCursor.CharPosture = com.sun.star.awt.FontSlant.REVERSE_ITALIC oCursor.CharColor = RGB(255,0,0) ' aplica estilo de pargrafo
47
Documentos do Writer
Verso 2
Note a atribuio da propriedade CharPosture a um valor enumerado REVERSE_ITALIC e, ainda, a alterao do estilo de pargrafo paraStyleName para Heading. Em se tratando de programao, os nomes permanecem em ingls, diferindo dos nomes apresentados pelo OpenOffice.org no Catlogo de Estilos.
O Writer disponibiliza diversos tipos de estilos. Temos estilos de pargrafos, estilos de pginas, estilos de caracteres, estilos de numerao e estilos de molduras. Todos eles esto agrupados dentro da Famlia de Estilos.
Famlia de Estilos Estilos de Estilos de Estilos de Estilos de Estilos de Pginas Pargrafos Caracteres Molduras Numerao ( ( ( ( ( estilo_1, estilo_1, estilo_1, estilo_1, estilo_1, estilo_2, estilo_2, estilo_2, estilo_2, estilo_2, ..., ..., ..., ..., ..., estilo_n estilo_n estilo_n estilo_n estilo_n ) ) ) ) )
O servio com.sun.star.style.StyleFamilies contm as famlias de estilos de um documento, para obter esta coleo faa:
Dim oFamiliasEstilos As Object oFamiliasEstilos = ThisComponent.getStyleFamilies()
Num documento texto, uma chamada ao mtodo getElementNames () retorna um vetor com os nomes das seguintes famlias: CharacterStyles ParagraphStyles FrameStyles PageStyles NumberingStyles
48
- estilos de caracteres - estilos de pargrafos - estilos de molduras - estilos de pginas - estilos de numerao
Introduo ao OpenOffice.org Basic
Verso 2
Documentos do Writer
O servio com.sun.star.style.StyleFamily contm os estilos de uma mesma famlia, para obter esta coleo, use o acesso nomeado, isto , getByName (nomeDaFamlia):
oEstParagrafos = ThisComponent.StyleFamilies.getByName(ParagraphStyles)
O servio com.sun.star.style.Style define as caractersticas de um estilo, para obter um estilo acesse-o pelo seu ndice, por exemplo, se o objeto oEstParagrafos foi definido, como acima:
oEstilo = oEstParagrafos (1)
retorna o segundo estilo dentro da coleo de estilos de pargrafos. A API do OpenOffice.org prov interfaces para facilitar o acesso a elementos de uma dada coleo. Ao trabalhar com estilos precisamos conhecer os mtodos: con.sun.star.container.XNameAcess getByName (sNome As String ) As Variant getElementNames ( ) As aStrings ( ) hasByName ( sNome As String ) As Boolean con.sun.star.container.XIndexAcess getCount ( ) As Long getByIndex ( nIndice As Long ) As Variant con.sun.star.container.XNameContainer insertByName ( sNome As String, oElemento As Variant) removeByName ( sNome As String ) O servio com.sun.star.style.PageStyle define as propriedades mais comuns da pgina, abaixo temos algumas delas: Propriedade BackColor LeftMargin RightMargin TopMargin BottomMargin Descrio Valor Long da cor de fundo da pgina Valor Long da margem esquerda em 1/100 mm Valor Long da margem direita em 1/100 mm Valor Long da margem superior em 1/100 mm Valor Long da margem inferior em 1/100 mm
49
Documentos do Writer
Verso 2
IsLandscape
Valores Long definindo o tamanho do papel (Size.Width e Size.Height) Valor Long definindo a largura da pgina em 1/100 mm Valor Long definindo a altura da pgina em 1/100 mm
HeaderLeftMargi Valor Long definindo a margem esquerda do cabealho em n 1/100 mm HeaderRightMarg Valor Long definindo a margem direita do cabealho em in 1/100 mm HeaderIsOn Determina se o cabealho est ativo na pgina (True / False)
FooterLeftMargin Valor Long definindo a margem esquerda do rodap em 1/100 mm FooterRightMargi Valor Long definindo a margem direita do rodap em 1/100 n mm FooterIsOn Determina se o rodap est ativo na pgina (True / False)
Vamos a um exemplo. Queremos exibir o nmero de estilos de pginas disponveis num documento, os seus nomes e a propriedade Size do estilo de pgina Padro (Standard). Os passos bsicos so: a) obter as familias de estilos do documento; b) obter os estilos de pginas; c) obter o vetor com os nomes dos estilos de pginas; d) usar um ndice para extrair cada um dos nomes; e) obter a pgina padro, usando o acesso nomeado. A sub-rotina Sub exibeEstilosPagina, a seguir, implementa o nosso exemplo:
Sub exibeEstilosPagina Dim oDoc As Object Dim oFamiliaEstilos As Object Dim oEstilosPagina As Object Dim oPaginaPadrao As Object Dim mNomesEstilosPagina As Variant Dim sEstilo As String Dim sMsg As String oDoc = ThisComponent
50
Verso 2
Documentos do Writer
' obtm a Famlia de Estilos (note o uso de oDoc) oFamiliaEstilos = oDoc.StyleFamilies ' obtm os Estilos de Pgina oEstilosPagina = oFamiliaEstilos.getByName("PageStyles") ' exibe quantidade de estilos de pgina MsgBox oEstilosPagina.Count ' obtm e exibe os nomes dos estilos de pginas mNomesEstilosPagina = oEstilosPagina.getElementNames() For n = LBound(mNomesEstilosPagina) To UBound(mNomesEstilosPagina) sMsg=sMsg + mNomesEstilosPagina(n) + " " Next n MsgBox sMsg,0,"Estilos de Pginas" ' obtm o Estilo de pgina Padro (Standard) oPaginaPadrao = oEstilosPagina.getByName("Standard") ' testando o tamanho da pgina lLPag = oPaginaPadrao.Size.Width lAPag = oPaginaPadrao.Size.Height MsgBox Str$(lLPag) + " " + Str$(lAPag) End Sub
A destacar, o acesso pelo ndice dentro do lao For ... Next, o acesso nomeado ao estilo da pgina Standard e o acesso propriedade Size. Note, ainda, a chamada ao mtodo getStylesFamilies ( ): oFamiliaEstilos = oDoc.StylesFamilies no OpenOffice.org Basic voc pode omitir o get e o set ao programar propriedades. Este exemplo pode ser usado como modelo para diversas operaes com estilos. Durante a formatao de texto, comum a criao e aplicao de novos estilos. Esta uma tarefa simples de executar dentro de uma macro. Para isto devemos seguir os passos: a) Obter as famlias de estilos do documento; b) Obter a famlia do grupo aonde ser criado o novo estilo; c) Criar uma instncia do objeto do novo estilo; d) Acrescentar o novo estilo ao grupo; e) Definir as propriedades do novo estilo; f) Aplicar o novo estilo. Vamos retomar a sub-rotina Sub processaTexto e acrescentar cdigo fonte para criar e aplicar um novo estilo de pargrafo. Digite (ou copie e cole) o cdigo abaixo, aps a ltima linha da Sub processaTexto, execute a macro e observe as definies de estilo do primeiro pargrafo do documento.
' -----------------------
51
Documentos do Writer
Verso 2
' cdigo para novo estilo ' ----------------------Dim oFamiliasEstilos As Object Dim EstilosParagrafo As Object Dim oNovoEstilo As Object ' obtem as familias de Estilos oFamiliasEstilos = oDoc.StyleFamilies ' obtem os estilos de pargrafos EstilosParagrafo = oFamiliasEstilos.getByName("ParagraphStyles") ' cria um novo estilo de paragrafo oNovoEstilo = oDoc.createInstance("com.sun.star.style.ParagraphStyle") ' acrescenta o novo estilo com o nome "novo_estilo" EstilosParagrafo.insertByName("novo_estilo",oNovoEstilo) ' define as propriedades do estilo oNovoEstilo.Name = "novo_estilo" oNovoEstilo.CharFontName = "Arial" oNovoEstilo.CharHeight = 16 oNovoEstilo.ParaAdjust = com.sun.star.style.ParagraphAdjust.CENTER oNovoEstilo.CharWeight = com.sun.star.awt.FontWeight.BOLD ' entao, aplica o novo estilo ao primeiro paragrafo oCursor.gotoStart(FALSE) oCursor.gotoEndOfParagraph(TRUE) oCursor.paraStyleName = "novo_estilo"
Acima, deve-se notar a criao de um novo objeto, no caso uma instncia de um estilo de pargrafo, com a chamada ao mtodo createInstance ( ... ). E, ainda, as definies das propriedades do novo estilo.
52
Verso 2
Documentos do Writer
Para seleo de texto, o mtodo getCurrentSelection ( ) opera da seguinte forma,: a) se nada estiver selecionado, retorna um objeto TextRange com a posio do cursor da vista; b) numa seleo simples, retorna um objeto TextRange com a seleo; c) numa seleo mltipla, retorna objetos TextRange para o cursor da vista e para cada uma das selees. No exemplo abaixo, obtemos as cadeias selecionadas, uma ou mais se mltipla seleo, e mudamos a cor de cada uma para vermelha:
Sub processaSelecao Dim oDoc As Object Dim oSel As Object Dim oCurTxt As Object oDoc = ThisComponent oSel = oDoc.getCurrentSelection() For i = 0 To oSel.Count-1 oCurTxt = oSel(i) oCurTxt.CharColor = RGB(255,0,0) Next i MsgBox oSel.Count End Sub
Note o acesso aos objetos selecionados atravs de um ndice e a criao de um cursor de texto antes da mudana de cor. Para extrair a cadeia selecionada, chame o mtodo getString ( ), como abaixo:
sCadeia = oSel ( i ).getString ( )
O mtodo getString ( ) retorna uma cadeia vazia para o primeiro objeto nos casos a) e c) acima. Insira o cdigo abaixo no lao For ... Next de processaSelecao e observe a sada:
MsgBox Str$ ( i ) + : + oSel ( i ).getString ( )
Analise como se d a criao do cursor de texto. Em seguida, como exerccio, faa com que a Sub processaSeleo aplique a cor tambm na palavra sob o cursor da vista. A API do OpenOffice.org tem, ainda, a interface com.sun.star.view.XSelectionSupplier, que implementa alguns mtodos de seleo pela interface grfica, entre eles: select ( oObjeto As Object ) As Boolean se possvel, seleciona o objeto oObjeto na interface grfica
Introduo ao OpenOffice.org Basic 53
Documentos do Writer
Verso 2
getSelection ( ) oObjeto As Variant obtm a seleo na interface grfica, pode retornar um objeto ou uma coleo de objetos Estes mtodos podem ser chamados atravs do controlador corrente do modelo (veja o trecho de cdigo abaixo). Existem, ainda, dois mtodos que podem ser teis para a identificao do contedo selecionado, so eles: getImplementationName ( ) As String retorna o nome da implementao do objeto getName ( ) As String retorna o nome do objeto, se o mesmo for nomeado, caso de grficos e tabelas.
Dim oControlador As Object oControlador = oDoc.getCurrentController() oSel = oControlador.getSelection() sNomeImpl = oSel.getImplementationName() sNome = oSel.getName()
Agora, altere a Sub processaSelecao, para alertar o usurio quando ele selecionar algo diferente de texto (dica, use getImplementationName).
Verso 2
Documentos do Writer
retorna uma sequncia de cadeias com os nomes dos objetos da coleo hasByName ( sNome As String ) As Boolean retorna True se o objeto de nome sNome existe na coleo A interface XIndexAccess define os mtodos a seguir: getByIndex ( iIndice As Long ) As Object retorna o objeto na posiao iIndice da coleo getCount ( ) As Long retorna o nmero de objetos da coleo A interface XEnumerationAccess define o mtodo: createEnumeration ( ) As Object <com.sun.star.container.XEnumeration> retorna um objeto XEnumeration A interface XEnumeration implementa os mtodos abaixo: hasMoreElements ( ) As Boolean retorna True se ainda existem elementos no recipiente nextElement ( ) As Variant retorna o prximo elemento A localizao simples, basta chamar o mtodo apropriado e a seguir, usar o acesso nomeado ou indexado para obter o objeto. A sub-rotina Sub localizaGraficos, abaixo, exibe os nomes de todos os objetos grficos do documento:
Sub localizaGraficos Dim oGraficos As Object Dim oGrafico As Object Dim n As Integer oGraficos = ThisComponent.getGraphicObjects() For n = 0 To oGraficos.Count -1 oGrafico = oGraficos (n) MsgBox oGrafico.getName() Next n MsgBox "Grficos no documento: " + Str$(oGraficos.Count) End Sub
Para apagar um grfico do seu documento, voc pode usar o bloco de cdigo:
oGrafico = oGraficos.getByName (Grfico2) oGrafico.dispose ()
55
Documentos do Writer
Verso 2
No exemplo a seguir, que demonstra a criao de uma enumerao, exibimos o comando de cada um dos campos de um documento:
Sub localizaCampos Dim oCampos As Object Dim oCampo As Object Dim n As Integer oCampos = ThisComponent.getTextFields().createEnumeration() n = 0 Do While (oCampos.hasMoreElements()) oCampo = oCampos.NextElement() MsgBox oCampo.getPresentation(True) n = n + 1 Loop MsgBox "Campos no documento: " + Str$(n) End Sub
Observe que a criao e o acesso aos elementos de uma enumerao sequncial e no indexado ou nomeado. O mtodo getPresentation() retorna o contedo do campo se o parmetro for False. Geralmente, para recuperar o objeto que nos interessa dentro da coleo retornada por um dos mtodos acima, precisamos conhecer o seu nome ou a sua posio dentro da coleo.
Verso 2
Documentos do Writer
getSearchString ( ) As String obtm a cadeia de busca setSearchString ( sCadeia As String ) define a cadeia de busca Eis algumas de suas propriedades: Propriedade SearchBackwards SearchWords SearchStyles Descrio Se True busca para o incio do documento Se True busca palavras completas Se True busca por um estilo
No exemplo a seguir, vamos localizar, no documento, todas as ocorrncias da cadeia ( ) e trocar a cor da fonte para vermelha. Digite (ou copie e cole) o cdigo abaixo e execute a subrotina.
Sub buscaTodas Dim oDoc As Object Dim oDescBusca As Object oDoc = ThisComponent oDescBusca = oDoc.createSearchDescriptor() oDescBusca.SearchWords = True oDescBusca.setSearchString ("( )") oResultado = oDoc.findAll( oDescBusca ) For n% = 0 To oResultado.Count - 1 oResultado(n%).CharColor = RGB(255,0,0) Next MsgBox "Ocorrncias de "+oDescBusca.getSearchString()+ _ + Str$(oResultado.Count) End Sub
A tarefa acima pode, tambm, ser executada com os mtodos findFirst e findNext:
oResultado = oDoc.findFirst( oDescBusca ) Do Until IsNull(oResultado) oResultado.CharColor = RGB(250,100,50) oResultado = oDoc.findNext(oResultado, oDescBusca ) Loop
A substituio de texto implementada pela interface XReplaceable, que herda as caractersticas de XSearchable. Ela prov os mtodos: createReplaceDescriptor ( ) As Object <com.sun.star.util.XReplaceDescriptor>
Introduo ao OpenOffice.org Basic 57
Documentos do Writer
Verso 2
retorna um descritor de substituio para as propriedades replaceAll ( xDescritor As Object <com.sun.star.util.XReplaceDescriptor>) As Long busca e substitui todas as ocorrncias, retorna o total de substituies O servio ReplaceDescriptor tem mtodos para as propriedades da cadeia: getReplaceString ( ) As String obtm a cadeia substituta setReplaceString ( sCadeia As String ) define a cadeia substituta Eis um exemplo simples de busca e substituio:
Sub substituiTodas Dim oDoc As Object Dim oDescritor As Object oDoc = ThisComponent oDescritor = oDoc.createReplaceDescriptor() oDescritor.setSearchString( "( )" ) oDescritor.setReplaceString( "()" ) n = oDoc.replaceAll(oDescritor) MsgBox n End Sub
Note que no temos um mtodo para substituio interativa. Porm, atravs da busca e edio, possvel implementar, com facilidade, este procedimento.
Para inserir na posio do cursor da interface grfica, crie o cursor de texto a partir do cursor da vista.
58 Introduo ao OpenOffice.org Basic
Verso 2
Documentos do Writer
A insero de arquivos grficos um pouco mais complicada, para isso voc deve: a) criar um objeto grfico; b) definir as suas propriedades; c) inserir o objeto. Observe a sub-rotina Sub inserirGrafico a seguir:
Sub inserirGrafico Dim oTxt As Object Dim oCursorTxt As Object Dim oGrafico As Object Dim sURL As String oTxt = ThisComponent.getText() oCursorTxt = oTxt.createTextCursor() oGrafico = ThisComponent.createInstance("com.sun.star.text.GraphicObject") sURL = "file:///D:/NAD/OPENOFFICE/HOWTO/FIGURAS/DIALOGO.JPG" oGrafico.GraphicURL = sURL oGrafico.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PARAGRAPH oTxt.insertTextContent(oCursorTxt.getStart(), oGrafico, False) End Sub
A chamada ao mtodo createInstance ( ) cria o objecto grfico, depois definimos as propriedades GraphicURL e AnchorType e, finalmente, inserimos o grfico chamando o mtodo insertTextContent ( ) com os parmetros adequados. A propriedade AnchorType pode assumir, ainda, os seguintes valores: AT_CHARACTER, AT_PAGE e AS_CHARACTER. O API do OpenOffice.org (verso 1.0.1) salva no documento apenas a URL do grfico. Logo, se voc remov-lo da sua localizao original, o Writer no ter como encontr-lo.
6.10 Tabelas
Uma tabela um conjunto de clulas organizadas por linhas e colunas, onde cada clula tem um nome, normalmente indicado por letras e nmeros. As letras referem-se s colunas e os nmeros s linhas. Contudo, se existirem clulas mescladas ou divididas, o conceito de coluna poder desaparecer e o esquema de nomeao torna-se complicado. Uma clula pode conter texto simples (cadeias e nmeros), grficos, frmulas e campos com vrias caractersticas de formatao. Uma tabela recebe um nome nico no documento, podendo servir como origem para grficos, ter o seu contudo ordenado e ser automaticamente formatada.
59
Documentos do Writer
Verso 2
A API do OpenOffice.org tem diversos servios e interfaces para lidar com tabelas, vejamos as principais. A interface com.sun.star.text.XTextTable encarrega-se do gerenciamento de tabelas num documento e contm os mtodos abaixo: initialize ( nLinhas As Long, nColunas As Long) Inicializa uma tabela, recebe o nmero de linhas e colunas como parmetros. getCellNames ( ) As Object < Strings > Obtm os nomes das clulas, retorna um conjunto de cadeias getCellByName ( sNomeCelula As String ) As Object < com.sun.star.table.XCell > Obtm a clula nomeada no parmetro, retorna um objeto XCell getRows ( ) As Object < com.sun.star.table.XTableRows > Obtm as linhas da tabela, retorna um objeto para XTableRows. getColumns ( ) As Object < com.sun.star.table.XTableColumns > Obtm as colunas da tabela, retorna um objeto para XTableColumns. createCursorByCellName ( sNomeCelula As String ) As Object < XTextTableCursor > Cria um cursor de tabela posicionado na clula nomeada no parmetro O servio TextTable possui diversas propriedades, eis algumas delas: Propriedade LeftMargin RightMargin Split TableBorder Descrio Contm a margem esquerda da tabela, valor Long Contm a margem direita da tabela, valor Long Um valor False impede a diviso da tabela em duas pginas Contm a descrio da borda da tabela
TableColumnSeparator Contm a descrio dos separadores de colunas da s tabela BackGraphicURL Contm a URL do grfico de fundo da clula
As interfaces XTableRows e XtableColumns, retornadas pelos mtodos getRows () e getColumns (), acima, possuem os mtodos a seguir: insertByIndex ( nIndice As Long, nTotal As Long ) removeByIndex ( nIndice As Long, nTotal As Long ) getElementType ( ) As Type hasElements ( ) As Boolean getByIndex ( ) As Variant getCount ( ) As Long
60 Introduo ao OpenOffice.org Basic
Verso 2
Documentos do Writer
A interface XTextTableCursor, retornada pelo mtodo createCursorByCellName, acima, prov os mtodos: getRangeName ( ) As String Retorna a extenso de clulas do cursor, isto , os nomes das clulas superior esquerda e inferior direita, por exemplo A2:D25 (note o separador : ). goLeft ( nQuant As Integer, bExpande As Boolean ) As Boolean goRight ( nQuant As Integer, bExpande As Boolean ) As Boolean goUp ( nQuant As Integer, bExpande As Boolean ) As Boolean goDown ( nQuant As Integer, bExpande As Boolean ) As Boolean gotoStart ( bExpande As Boolean ) gotoEnd ( bExpande As Boolean ) Mtodos para movimentao e seleo, nQuant a quantidade de clulas e, se bExpande for True, extende a seleo durante o deslocamento do cursor. gotoCellByName (sNome As String, bExpande As Boolean ) As Boolean Desloca o cursor para a clula nomeada no parmetro. mergeRange ( ) As Boolean splitRange ( nQuant As Integer, bHoriz As Boolean ) As Boolean Mtodos para fundir e dividir clulas. Atravs do servio TextTableCursor podemos efetuar a formatao das clulas, pois, ele inclui os servios CharacterProperties e ParagraphProperties.
A interface com.sun.star.table.XCellRange define os mtodos abaixo para lidar com extenses de clulas: getCellByPosition ( nColuna As Long, nLinha As Long ) As Object < XCell > getCellRangeByPosition ( nEsq, nSup, nDir, nInf ) As Object < XCellRange > getCellRangeByName ( sRange As String ) As Object < XCellRange > O servio com.sun.star.table.CellRange inclui com.sun.star.table.CellProperties, que define as propriedades de uma ou mais clulas. Eis algumas: Propriedade CellBackColor HoriJustify Descrio Valor Long com a cor de fundo da clula Alinhamento horizontal do contedo da clula (enum CellHoriJustify)
61
Documentos do Writer
Verso 2
VertJustify IsTextWrapped Orientation RotateAngle TableBorder TopBorder BottomBorder LeftBorder RightBorder NumberFormat CellProtection
do
contedo
da
clula
(enum
Se True, o texto muda de linha automaticamente Orientao do contedo da clula (enum CellOrientation) Define a rotao do contedo da clula (em 1/100 graus) Descreve a borda das clulas (struct TableBorde) Descreve a BorderLine) Descreve a BorderLine) Descreve a BorderLine) borda borda borda superior inferior esquerda de de de cada cada cada clula clula clula (struct (struct (struct
Descreve a borda direita de cada clula (struct BorderLine) ndice do formato numrico usado nas clulas (servio NumberFormatter) Descreve a proteo da clula (servio CellProtection)
A interface com.sun.star.table.XCell oferece os mtodos abaixo para manipular o contedo de uma clula: getFormula ( ) As String setFormula ( sFormula As String ) mtodos para obter ou definir a frmula de uma clula getValue ( ) As Double setValue ( nValor As Double ) mtodos para obter ou definir o valor de uma clula getType ( ) As Long < com.sun.star.table.CellContentType > retorna o tipo do contedo de uma clula, como enumerado em CellContentType getError ( ) As Long retorna o erro de uma clula, til para rastrear erros em frmulas O nome de uma tabela pode ser obtido ou definido com os mtodos a seguir, da interface com.sun.star.container.XNamed: getName ( ) As String setName ( sNomeTabela As String ) O contedo de uma tabela pode ser ordenado com a interface com.sun.star.util.XSortable e seus mtodos:
62 Introduo ao OpenOffice.org Basic
Verso 2
Documentos do Writer
createSortDescriptor ( ) As Variant <com.sun.star.beans.PropertyValue> retorna um descritor para as propriedades da ordenao sort (xDescritor As Variant <com.sun.star.beans.PropertyValue> ) executa a ordenao conforme o descritor Seguem algumas das propriedades do descritor de ordenao (SortDescriptor): Propriedade IsCaseSensitive SortAscending SortColumns Descrio Se True, considera maisculas / minsculas Define a ordem da ordenao (??) Se True ordena as colunas, seno ordena as linhas.
O servio com.sun.star.table.TableSortDescriptor inclui o servio SortDescriptor e possui as propriedades abaixo: Propriedade SortFields MaxFieldCount Orientation ContainsHeader Descrio Descreve os campos <com.sun.star.util.SortField> de ordenao
Define o nmero mximo de campos, somente leitura Define a orientao da <com.sun.star.table.TableOrientation> Se True, no ordena a primeira linha ou coluna ordenao
hora de apresentar um exemplo. Inicialmente, vamos criar, inicializar e inserir uma tabela, com cinco linhas e trs colunas, no incio do documento corrente. Depois, vamos definir os ttulos das colunas. Digite o cdigo abaixo, execute e observe o resultado:
Sub criaTabela Dim oTxt As Object Dim oTab As Object ' ' cria, inicializa e insere a tabela no inicio do documento oTxt = ThisComponent.getText() oTab = ThisComponent.createInstance("com.sun.star.text.TextTable") oTab.initialize(5,3) oTxt.insertTextContent(oTxt.createTextCursor(), oTab, FALSE) ' ' preenche os ttulos das colunas (clulas A1, B1 e C1 ) Dim oCelula As Object oCelula = oTab.getCellByName("A1") oCelula.setString("Coluna A") oCelula = oTab.getCellByName("B1") oCelula.setString("Coluna B") oCelula = oTab.getCellByName("C1") oCelula.setString("Coluna C")
63
Documentos do Writer
Verso 2
End Sub
Primeiro criamos o objeto tabela com createInstance (), depois definimos as linhas e colunas com initialize (), inserimos a tabela no documento com uma chamada ao mtodo insertTextContent ( ) e, ento , obtemos cada uma das clulas do cabealho e definimos o seu contedo. O bloco de cdigo abaixo demonstra o emprego do cursor de tabela, navegao, formatao e mesclagem de clulas. Acrescente-o Sub criaTabela.
' ' cria um cursor de tabela na clula CellNames(0) = A1 Dim oCurTab As Object oCurTab = oTab.createCursorByCellName(oTab.CellNames(0)) ' seleciona as clulas A1, B1 e C1 oCurTab.gotoStart(False) oCurTab.goRight(2, True) ' Aplica o estilo de pargrafo Ttulo na seleo oCurTab.paraStyleName = "Heading" ' exibe o nome da extenso selecionada (range) ' Note a forma de apresentao (invertida) MsgBox oCurTab.getRangeName() ' ' nomeia as celulas a partir da linha 2 e ' escreve nmero da linha na coluna C Dim sNomes() As Variant Dim sNomeCelula As String sNomes = Array("A","B","C") For i% = 1 To 4 For j% = 1 To 3 sNomeCelula = sNomes(j%-1)+ Str$(i%+1) oCelula = oTab.getCellByName(sNomeCelula) If (j% - 1 = 2) Then ' define um valor numrico para a clula oCelula.setValue(i% + 1) Else oCelula.setString(sNomeCelula) End If Next j% Next i% ' ' define uma frmula (soma de C2 at C4) para a clula C5 oCelula = oTab.getCellByName("C5") oCelula.setFormula("sum <C2:C4>") ' ' funde as clulas A5 e B5 e muda seu contedo oCurTab.gotoCellByName("A5", False) oCurTab.goRight(1, True) oCurTab.mergeRange() oCelula = oTab.getCellByName("A5") oCelula.setString("Total")
Note a criao do cursor da tabela com createCursorByCellNames (...), o uso do cursor para formatao, o uso dos mtodos setValue () e setFormula () e a seleo e mesclagem das clulas A5 e B5.
64 Introduo ao OpenOffice.org Basic
Verso 2
Documentos do Writer
No prximo bloco de cdigo, veremos a ordenao de uma extenso de clulas (A2:C4) da nossa tabela. Basta inserir o cdigo na Sub criaTabela e executar para ver o resultado.
' ' ordena de A2 at C4 Dim oCampoOrd(0) As New com.sun.star.util.SortField Dim oDescrOrd As Variant Dim oExtensao As Object ' ' define a extenso a ser ordenada oExtensao = oTab.getCellRangeByName("A2:C4") ' define o campo de ordenao e suas propriedades oCampoOrd(0).Field = 0 oCampoOrd(0).SortAscending = False oCampoOrd(0).FieldType = com.sun.star.util.SortFieldType.ALPHANUMERIC ' cria o descritor de ordenao oDescrOrd = oTab.createSortDescriptor() ' define as propriedades do descritor oDescrOrd(0).Name = "SortFields" oDescrOrd(0).Value = oCampoOrd() oDescrOrd(1).Name = "ContainsHeader" oDescrOrd(1).Value = False oDescrOrd(2).Name = "SortColumns" oDescrOrd(2).Value = False ' ordena a extenso oExtensao.sort(oDescrOrd())
Note que iniciamos com a declarao das variveis, criamos uma extenso de clulas com uma chamada ao mtodo getCellRangeByName (), definimos as propriedades do campo de ordenao, criamos o descritor e definimos as suas propriedades (o campo de ordenao uma propriedade do descritor) e, finalmente, invocamos o mtodo sort () para executar a sua tarefa. Antes de terminar esta seo, vejamos como se d o acesso s tabelas existentes num documento texto. O processo o mesmo j visto na seo Localizando Objetos. O mtodo getTextTables () da interface XTextTablesSupplier retorna uma coleo contendo as tabelas do documento. Ele percorre o documento do incio para o final. getTextTables () As Object <com.sun.star.container.XNameAccess> O exemplo abaixo demonstra a localizao das tabelas de um documento, depois obtm as colees de linhas e colunas da tabela com o nome Tabela3.
Sub localizaTabelas Dim oTabelas As Object Dim oTabela As Object Dim oLinhas As Object Dim oColunas As Object Dim n As Integer oTabelas = ThisComponent.getTextTables()
65
Documentos do Writer
Verso 2
For n = 0 To oTabelas.Count -1 oTabela = oTabelas.getByIndex(n) MsgBox oTabela.getName() Next n MsgBox "Tabelas no documento: " + Str$(oTabelas.Count) ' If (oTabelas.hasByName (Tabela3)) Then oTabela = oTabelas.getByName("Tabela3") oLinhas = oTabela.getRows() oColunas = oTabela.getColumns() MsgBox Str$(oLinhas.Count)+" - "+Str$(oColunas.Count) End If End Sub
Lembre-se que, para acessar uma tabela, voc deve conhecer o seu nome ou o seu ndice dentro da coleo e, em seguida, chamar o mtodo getByName () ou getByIndex (). Aps obter a tabela desejada, use as tcnicas j apresentadas para editar o seu contedo.
6.11 Desenhos
A API do OpenOffice.org possui diversos servios e interfaces para operaes com desenhos num documento, atravs de uma macro. Nesta seo, veremos como usar alguns destes servios e interfaces. O servio com.sun.star.text.Shape, contm muitas propriedades relacionadas aos objetos de desenho, seguem algumas delas: Propriedade AnchorType HoriOrient VertOrient LeftMargin RightMargin TopMargin BottomMagin Descrio Tipo da ncora Orientao horizontal Orientao vertical Margem esquerda Margem direita Margem superior Margem inferior
O servio com.sun.star.drawing.Shape contm proriedades adicionais, como Name, que permite definir um nome para o desenho, e suporta as interfaces: com.sun.star.beans.XPropertySet com.sun.star.drawing.XShape com.sun.star.drawing.XShapeDescriptor
66
Verso 2
Documentos do Writer
A interface XShape, acima, prov mtodos para definir a posio e o tamanho do desenho: getPosition ( ) As Object < com.sun.star.awt.Point > setPosition ( Ponto As Object < com.sun.star.awt.Point > ) getSize ( ) As Object < com.sun.star.awt.Size > set Size ( Tamanho As Object < com.sun.star.awt.Size > ) A interface XShapeDescriptor contm o mtodo a seguir, que retorna uma cadeia com o tipo de desenho: getShapeType ( ) As String Atravs da interface com.sun.star.lang.XMultiServiceFactory, criamos o objeto desenho usando o mtodo: createInstance ( sServico As String ) As Object < com.sun.star.uno.XInterface > O mdulo com.sun.star.drawing da API do OpenOffice.org contm diversos servios para a criao de objetos de desenho e so usados como parmetro da funo createInstance ( ). Estes servios contm, alm de propriedades comuns, outras especficas. Eis alguns deles: com.sun.star.drawing.EllipseShape com.sun.star.drawing.RectangleShape los com.sun.star.drawing.LineShape usado para desenhar crculos e elipses usado para desenhar retnguusado para desenhar linhas
A interface com.sun.star.drawing.XShapes define mtodos para adicionar e remover desenhos do documento: add ( Desenho As Object < com.sun.star.drawing.Shape > ) remove ( Desenho As Object < com.sun.star.drawing.Shape > ) A interface com.sun.star.text.XText tambm define os mtodos abaixo, apresentados noutras sees, para adicionar e remover desenhos do documento: insertTextContent ( ) removeTextContent ( ) A interface com.sun.star.drawing.XDrawPageSupplier define o mtodo abaixo para obter a pgina de desenho do documento: getDrawPage ( ) As Object < com.sun.star.drawing.DrawPage >
Introduo ao OpenOffice.org Basic 67
Documentos do Writer
Verso 2
Para a manipulao de desenhos no Writer e Calc, o OpenOffice.org utiliza os mecanismos bsicos de desenho do Draw. Uma das principais diferenas, que no Draw existem vrias pginas de desenho, enquanto no Writer existe apenas uma. Vejamos como inserir desenhos num documento, atravs de uma macro que usa alguns dos mtodos e propriedades apresentados. Crie um documento do Writer e digite o cdigo fonte abaixo no IDE Basic, em seguida execute a macro e observe o resultado.
Sub criaDesenho ' Dim oDoc As Object Dim oTexto As Object Dim oCursor As Object Dim oRetang As Object Dim oElipse As Object Dim oPagDes As Object Dim oTamanho As New com.sun.star.awt.Size Dim oPonto As New com.sun.star.awt.Point oDoc = ThisComponent oTexto = oDoc.getText() oCursor = oTexto.createTextCursor() ' insere dois novos pargrafos no final do texto oCursor.gotoEnd(False) oTexto.insertControlCharacter(oCursor, _ com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False) oTexto.insertControlCharacter(oCursor, _ com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False) oCursor.gotoPreviousParagraph(False) ' cria um objeto retngulo e um objeto elipse oRetang = oDoc.createInstance("com.sun.star.drawing.RectangleShape") oElipse = oDoc.createInstance("com.sun.star.drawing.EllipseShape") ' define o tamanho do retngulo e elipse oTamanho.Height = 4000 oTamanho.Width = 10000 oRetang.setSize(oTamanho) oRetang.Name = "Ret_1" oTamanho.Height = 3000 oTamanho.Width = 6000 oElipse.setSize(oTamanho) oElipse.Name = "Eli_1" ' define a posio do retngulo a direita da elipse oPonto.X = 6100 oPonto.Y = 0 oRetang.setPosition (oPonto) ' define a ncora no pargrafo oRetang.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PARAGRAPH oElipse.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PARAGRAPH ' insere na posio do cursor de texto oTexto.insertTextContent(oCursor,oElipse,FALSE) oTexto.insertTextContent(oCursor,oRetang,FALSE) oPosRet = oRetang.getPosition() MsgBox Str$(oPosRet.X)+" - "+Str$(oPosRet.Y) ' cria uma linha
68
Verso 2
Documentos do Writer
oLinha = oDoc.createInstance( "com.sun.star.drawing.LineShape" ) ' define o tamanho da linha oTamanho.Height = 30 oTamanho.Width = 6000 oLinha.setSize (oTamanho) ' define a posio da linha oPonto.X = 6000 oPonto.Y = 10000 oLinha.setPosition (oPonto) ' obtm a pgina de desenho do documento oPagDes = oDoc.getDrawPage() ' adiciona a linha na primeira pgina oPagDes.add (oLinha) ' End Sub
Comeamos inserindo pargrafos no final do texto, a seguir criamos dois objetos de desenho, um retngulo e uma elipse, definimos a suas propriedades e usamos o mtodo insertTextContent ( ) para adicionar os objetos no documento. Depois, criamos uma linha, obtemos a pgina de desenho do documento e adicionamos a linha com o mtodo add ( ). Para encerrar esta seo, vejamos um exemplo que identifica os objetos de desenho existentes no nosso documento. Crie a macro abaixo num documento contendo desenhos, molduras e grficos. Em seguida execute e observe a sada.
Sub obtemDesenhos ' ' obtem outros objetos alm de desenhos, ex: molduras ' Dim oDoc As Object Dim oPage As Object oDoc = ThisComponent oPage = oDoc.getDrawPage() sMsg = "" nNrDes = oPage.getCount() For i = 0 To nNrDes - 1 oShape = oPage.getByIndex ( i ) ' obtem nome se definido na criao 'sMsg = sMsg + oShape.getName() + chr$(10) sMsg = sMsg + oShape.getShapeType() + chr$(10) Next i MsgBox sMsg + Str$(nNrDes) End Sub
Note que outros objetos baseados no servio Shape, como molduras, tambm so identificados. O mtodo getName ( ), somente retorna o nome, se o objeto foi nomeado durante a criao do desenho.
69
Documentos do Calc
Verso 2
7 Documentos do Calc
7.1 Introduo
Um documento do Calc contm uma ou mais folhas de planilhas. Cada planilha formada por clulas organizadas em linhas e colunas, de modo bem parecido com o de uma tabela do Writer. Estas clulas contm, basicamente, texto, que pode representar uma cadeia de caracteres, um valor numrico, um campo ou uma frmula. Cada um dos elementos acima (documento, planilha e clula), possui caractersticas prprias. Algumas podem ser alteradas, como por exemplo: estilo de pgina, formato numrico, pargrafo e fonte. Alm das tarefas comuns de edio, podemos aplicar, sobre o contedo de uma planilha operaes como: ordenao, filtragem, sub-totalizao, gerao de grficos, etc. Podemos, tambm, inserir, numa planilha, objetos como imagens, desenhos, dados de uma fonte externa e objetos OLE. Como voc j deve ter notado, dado a riqueza e o poder das operaes com documentos do Calc, a sua programao um assunto extenso. Nas prximas sees, tentarei apresentar o bsico.
7.2 Planilhas
As funes bsicas j abordadas no captulo Trabalhando com Documentos, podem ser usadas tambm com documentos do Calc. Assim, esta seo vai cobrir algumas operaes sobre as folhas das planilhas de um documento do Calc. O mdulo com.sun.star.sheet, da API do OpenOffice.org, contm os principais servios, interfaces e grupos de constantes relacionados com planilhas. O servio SpreadsheetDocument representa o modelo de um documento do Calc, contendo atributos e uma ou mais planilhas. A interface XSpreadsheetDocument prov o mtodo getSheets (), que retorna uma coleo com as planilhas do documento. getSheets ( ) As Object <com.sum.star.sheet.XSpreadsheets> Os objetos desta coleo podem ser acessados pelos seus nomes ou ndices. Podemos, ainda, criar uma enumerao e usar o acesso seqncial. A interface XSpreadsheets, retornada por getSheets (), define os mtodos abaixo:
70
Verso 2
Documentos do Calc
insertNewByName ( sNome As String, iPosicao As Integer ) moveByName ( sNome As String, iDestino As Integer ) copyByName ( sNomeOrigem As String, sNomeCopia As String, iPosicao As Integer ) Para fixar os conceitos acima, no exemplo a seguir, vamos criar um documento e efetuar algumas operaes com planilhas.
Sub criaDocCalc Dim oDesk As Variant Dim oDoc As Object Dim mProp() As Variant Dim sURL As String ' cria documento do Calc oDesk = createUnoService("com.sun.star.frame.Desktop") sUrl = "private:factory/scalc" oDoc = oDesk.LoadComponentFromURL(sUrl,"_blank",0,mProp()) ' exibe a propriedade casas decimais padro do documento MsgBox oDoc.StandardDecimals ' ' navega pelas planilhas existentes no documento Dim oPlanilhas As Object Dim oPlanilha As Object Dim sMsg As String ' oPlanilhas = oDoc.getSheets() sMsg = "" For n=0 To oPlanilhas.Count - 1 oPlanilha = oPlanilhas.getByIndex(n) sMsg = sMsg + oPlanilha.getName() + Chr$(13) Next n MsgBox sMsg + Str$(oPlanilhas.Count) ' acesso nomeado If oPlanilhas.hasByName("Planilha2") Then oPlanilha = oPlanilhas.getByName("Planilha2") MsgBox oPlanilha.PageStyle End If ' insere uma folha no incio oPlanilhas.insertNewByName("Planilha4",0) MsgBox oPlanilhas.Count ' move para o final oPlanilhas.moveByName("Planilha4",4) End Sub
Note os parmetros para a criao do documento, o acesso aos objetos da coleo e o uso dos mtodos para inserir e mover uma folha de planilha. O servio SpreadsheetView fornece funcionalidades relacionadas vista corrente de um documento do Calc. Ele inclui o servio SpreadsheetViewSettings, que define algumas propriedades de cada uma das planilhas do documento e, a sua interface XspreadsheetView, traz os mtodos a seguir, para a definio da planilha ativa no documento: getActiveSheet ( ) As Object < XSpreadsheet >
Introduo ao OpenOffice.org Basic 71
Documentos do Calc
Verso 2
setActiveSheet ( oPlanilha As Object < XSpreadsheet >) Lembre-se que as operaes relacionadas com a interface grfica so gerenciadas pelo objeto controlador do documento. Digite o cdigo fonte abaixo no final da Sub criaDocCalc, execute e observe o resultado.
' ativa a Planilha4 na GUI If oPlanilhas.hasByName("Planilha4") Then MsgBox oDoc.getCurrentController().getActiveSheet().getName() oPlanilha = oPlanilhas.getByName("Planilha4") oDoc.getCurrentController().setActiveSheet(oPlanilha) End If
Inicialmente, exibimos o nome da planilha ativa e, ento, selecionamos a planilha de nome Planilha4. Como j demonstrado no captulo Documentos do Writer, podemos alterar o contedo de um documento independente da interface grfica.
7.3 Editando
Para editar o contedo de uma ou mais clulas, devemos ter em mente o seguinte: a) obter a planilha onde se encontram as clulas a editar; b) obter uma extenso contendo as clulas a serem editadas, este passo opcional, pois uma planilha uma extenso de clulas; c) obter a clula a editar; d) definir o contedo da clula. O item a) deve ser solucionado com o uso do mtodo getSheets (), associado ao acesso nomeado, indexado ou enumerado, como demonstrado na seo sobre Planilhas. As ferramentas para solucionar os itens b), c) e d) tambm j foram apresentadas na seo sobre Tabelas e envolve os mtodos das interfaces XCellRange e XCell. Mtodos da interface com.sun.star.table.XCellRange: getCellByPosition ( nColuna As Long, nLinha As Long ) As Object < XCell > getCellRangeByPosition ( nEsq, nSup, nDir, nInf ) As Object < XCellRange > getCellRangeByName ( sRange As String ) As Object < XCellRange > Devemos lembrar que a posio de uma clula, dentro de uma extenso (range), relativa ao incio da extenso.
72
Verso 2
Documentos do Calc
Mtodos da interface com.sun.star.table.XCell: getFormula ( ) As String setFormula ( sFormula As String ) getValue ( ) As Double setValue ( nValor As Double ) getType ( ) As Long < com.sun.star.table.CellContentType > getError ( ) As Long Para relembrar, vejamos um exemplo de edio do contedo das clulas de uma planilha. Digite o cdigo abaixo, execute e observe o resultado.
Sub editaPlanilha Dim oDesk As Variant Dim oDoc As Object Dim mProp() As Variant Dim sURL As String ' ' cria documento do Calc oDesk = createUnoService("com.sun.star.frame.Desktop") sUrl = "private:factory/scalc" oDoc = oDesk.LoadComponentFromURL(sUrl, "_blank", 0, mProp()) ' ' edita clulas da planilha Dim oPlanilha As Object Dim oCelula As Object Dim sTitCol() As String ' escreve os titulos das colunas sTitCol = Array ("CDIGO","MATERIAL","QUANT","P. UNIT","P. TOTAL") oPlanilha = oDoc.getSheets().getByIndex(0) For i% = 0 To 4 oCelula = oPlanilha.getCellByPosition(i%, 0) oCelula.setString(sTitCol(i%)) Next i% ' ' preenche as clulas com texto, valor e formula For i% = 1 To 6 For j% = 0 To 4 oCelula = oPlanilha.getCellByPosition(j%, i%) If (j% = 0) Then If i% < 4 Then oCelula.setString("A" + Str$(i%)) Else oCelula.setString("A" + Str$(i%-3)) End If ElseIf (j% = 1) Then oCelula.setString("Material de construo " + Str$(i%)) ElseIf (j% = 2) Then oCelula.setValue(i% * j%) ElseIf (j% = 3) Then oCelula.setValue(100 * Rnd()) Else
73
Documentos do Calc
Verso 2
sLinha = Trim$(Str$(i%+1)) sFormula = "=C" + sLinha + " * " + "D" + sLinha oCelula.setFormula(sFormula) End If Next j% Next i% ' resumo oCelula = oPlanilha.getCellByPosition(0, 7) oCelula.setString("CUSTO TOTAL") ' sFormula = "=Sum(E1:E6)" oCelula = oPlanilha.getCellByPosition(4, 7) oCelula.setFormula(sFormula) ' End Sub
Note que, na segunda chamada do mtodo setFormula (), definimos a frmula usando o nome de uma funo em ingls. Para utilizar os nomes das funes exibidos pela interface grfica, use a propriedade FormulaLocal, do servio com.sun.star.sheet.SheetCell., por exemplo:
oCelula = oPlanilha.getCellByPosition(4, 7) sFormula = "=Soma(E1:E6)" oCelula.FormulaLocal = sFormula
O servio SheetCell define as seguintes propriedades: Propriedade Position Size FormulaLocal FormulaResultType ConditionalFormat Descrio Somente leitura, posio da clula na planilha Somente leitura, tamanho da clula em 1/100 mm Cadeia com o nome local da frmula Somente leitura, tipo do resultado de uma frmula Definies de formatao condicional da clula
ConditionalFormatLoc Definies locais de formatao condicional da clula al Validation ValidationLocal Definies de validao da clula Definies locais de validao da clula
Na prxima seo, trataremos da criao e emprego de um cursor, outra funcionalidade dos documentos do Calc.
74
Verso 2
Documentos do Calc
75
Documentos do Calc
Verso 2
A interface XCellCursor, do servio CellCursor, prov os seguintes mtodos, j explicados na seo Tabelas, do captulo Documentos do Writer: gotoStart ( ) gotoEnd ( ) gotoNext ( ) gotoPrevious ( ) gotoOffSet ( nDeslocColuna As Long, nDeslocLinha As Long ) Para demonstrar o uso de um cursor, digite o cdigo fonte abaixo e execute, observando o resultado.
Sub criaCursorCelulas Dim oDesk As Variant Dim oDoc As Object Dim mProp() As Variant Dim sURL As String ' ' cria documento do Calc oDesk = createUnoService("com.sun.star.frame.Desktop") sUrl = "private:factory/scalc" oDoc = oDesk.LoadComponentFromURL(sUrl, "_blank", 0, mProp()) ' ' trabalha com um cursor Dim oPlan As Object Dim oCursor As Object oPlan = oDoc.getSheets().getByIndex(0) oCursor = oPlan.createCursorByRange(oPlan.getCellByPosition(0,0)) ' suporta XSpreadSheet MsgBox oCursor.getSpreadsheet().getName() ' edita algumas clulas ' note que a posio da clula relativa oCursor.getCellByPosition(0,0).setFormula("Clula A1") oCursor.gotoNext() oCursor.getCellByPosition(0,0).setFormula("Clula B1") oCursor.gotoNext() oCursor.getCellByPosition(0,0).setFormula("Clula C1") ' move o cursor 5 celulas abaixo oCursor.gotoOffSet(0,5) oCursor.getCellByPosition(0,0).setFormula("Abaixo de C1") oCursor.CharHeight = 16 ' obtm toda a rea em uso oCursor.gotoStartOfUsedArea(False) oCursor.gotoEndOfUsedArea(True) ' obtem e exibe o endereo do cursor (ndices) oEnd = oCursor.getRangeAddress() MsgBox Str$(oEnd.Sheet)+Str$(oEnd.StartColumn)+Str$(oEnd.StartRow) MsgBox Str$(oEnd.Sheet)+Str$(oEnd.EndColumn)+Str$(oEnd.EndRow) End Sub
76
Verso 2
Documentos do Calc
Aqui, usamos o mtodo createCursorByRange ( ), mas poderamos ter usado createCursor ( ). Note que, para definir o contedo de uma clula, devemos obt-la chamando o mtodo getCellByPosition ( ), com a posio relativa ao incio da extenso de clulas do cursor. Observe, ainda, como se d a seleo e identificao da rea usada pela planilha.
O trecho de cdigo a seguir obtm uma extenso de clulas contnuas selecionada e exibe os ndices da planilha, coluna inicial e final, linha inicial e final.
' para oExt = oEnd = MsgBox MsgBox uma extenso: com.sun.star.sheet.CellRange oDoc.getCurrentSelection() oExt.getRangeAddress() Str$(oEnd.Sheet)+Str$(oEnd.StartColumn)+Str$(oEnd.StartRow) Str$(oEnd.EndColumn)+Str$(oEnd.EndRow)
Podemos, ainda, obter a seleo de extenses de clulas no contnuas, numa mesma planilha ou em planilhas diferentes, o bloco de cdigo fonte abaixo lida com esta situao. Num documento do Calc, selecione extenses no contnuas, crie a macro e execute para ver a sada.
Sub selecaoExtensoes Dim oDoc As Object Dim oExts As Object oDoc = ThisComponent ' oExts suporta com.sun.star.sheet.SheetCellRanges oExts = oDoc.getCurrentSelection() MsgBox oExts.getCount() oEnd = oExts.getRangeAddresses()
77
Documentos do Calc
Verso 2
For n=0 To UBound(oEnd) MsgBox Str$(oEnd(n).Sheet)+Str$(oEnd(n).StartColumn)+Str$(oEnd(n).StartRow) Next n MsgBox oExts.getRangeAddressesAsString() End Sub
O mtodo getCurrentSelection ( ) lida com outros objetos, como grficos ou desenhos. Podemos usar o mtodo getImplementationName ( ) ou supportsService ( ), para tentar uma identificao inicial do objeto selecionado. Temos, ainda, a interface com.sun.star.view.XSelectionSupplier, que define mtodos para seleo pela interface grfica, entre eles: select ( oObjeto As Object ) As Boolean se possvel, seleciona o objeto oObjeto na interface grfica. getSelection ( ) oObjeto As Variant obtm a seleo na interface grfica, pode retornar um objeto ou uma coleo de objetos. Estes mtodos podem ser chamados atravs do objeto controlador do modelo, como abaixo:
' seleciona uma extenso de clulas na planilha ' oDoc = ThisComponent oCtr = oDoc.getCurrentController ( ) oPlan = oDoc.Sheets ( 0 ) oExt = oPlan.getCellRangeByPosition ( 0, 1, 4, 6 ) If ( oCtr.select ( oExt ) ) Then MsgBox "Selecionado na vista" Else MsgBox "No selecionado" End If
A API do OpenOffice.org oferece outras funcionalidades, como a seleo de uma extenso de clulas durante a execuo de uma macro, a serem abordadas em outras sees deste documento.
7.6 Formatando
A apresentao final de um trabalho muito importante e o Calc oferece uma vasta gama de possibilidades para nos auxiliar na formatao dos nossos documentos.
78
Verso 2
Documentos do Calc
O servio com.sun.star.table.TableColumn define as propriedades abaixo para formatao de colunas: Propriedade Width OptimalWidth IsVisible IsStartOfNewPage Descrio Define a largura da coluna em 1/100 mm Se True, ajusta automaticamente a largura da coluna Se True, a coluna ser exibida Se True, insere uma quebra horizontal de pgina nesta coluna
Outras propriedades para a formatao de clulas so cobertas pelos servios: com.sun.star.table.CellProperties com.sun.star.table.TableBorder com.sun.star.table.BorderLine O servio CellProperties contm diversas propriedades. As mais importantes foram apresentadas no captulo Documentos do Writer, na seo sobre Tabelas. Vamos aplicar alguma formatao ao exemplo criado pela Sub editaPlanilha. Adicione o cdigo fonte abaixo no final da sub-rotina, execute e observe a sada:
' Formatao
79
Documentos do Calc
Verso 2
Dim oExtensao As Object Dim oLinha As Object Dim oColuna As Object ' ' formata pargrafos e caracteres oExtensao = oPlanilha.getCellRangeByPosition(0, 0, 5, 0) oExtensao.CharHeight = 12 oExtensao.CharWeight = com.sun.star.awt.FontWeight.BOLD oExtensao.ParaAdjust = com.sun.star.style.ParagraphAdjust.CENTER ' ajusta a altura da linha 1 oLinha = oPlanilha.getRows().getByIndex(0) oLinha.OptimalHeight = True ' ajusta a largura da coluna B oColuna = oPlanilha.getColumns().getByIndex(1) oColuna.OptimalWidth = True
Mesclando Clulas
Numa planilha, podemos mesclar clulas, a interface com.sun.star.util.XMergeable define os mtodos abaixo, com esta finalidade: merge ( bMerge As Boolean ) Se bMerge True mescla a rea do objeto, seno separa. getIsMerged ( ) As Boolean Retorna True se a rea do objeto estiver mesclada, seno retorna False
Inserindo Bordas
Outro aspecto importante na apresentao de uma planilha a colocao de bordas em torno das clulas. O servio CellProperties contm as seguintes propriedades, que definem o tipo de borda de uma clula ou extenso de clulas: Popriedade TableBorder TopBorder BottomBorder RightBorder LeftBorder Descrio Define a borda de uma clula ou extenso de clulas Define a borda superior de cada clula da extenso Define a borda inferior de cada clula da extenso Define a borda direita de cada clula da extenso Define a borda esquerda de cada clula da extenso
O principal elemento de cada uma destas propriedades a estrutura BorderLine, contendo, dentre outros, os campos Color e OuterLineWidth para a cor e a espessura da linha. Para a
80
Verso 2
Documentos do Calc
propriedade TableBorder, podemos definir quatro linhas: TopLine, BottomLine, RightLine e LeftLine. Prosseguindo com o nosso exemplo, vamos mesclar algumas clulas e, depois, definir bordas para a nossa planilha. Acrescente o cdigo fonte a seguir na sub-rotina Sub editaPlanilha e observe o resultado da execuo:
' mescla clulas oExtensao = oPlanilha.getCellRangeByPosition(0, 7, 3, 7) oExtensao.merge(True) ' Define Borda Dim oBorda As New com.sun.star.table.TableBorder Dim oLinBorda As New com.sun.star.table.BorderLine ' oExtensao = oPlanilha.getCellRangeByPosition(0, 0, 4, 7) ' define a espessura e a cor da linha da borda oLinBorda.OuterLineWidth = 30 oLinBorda.Color = CLng( "&H000099" ) oExtensao.setPropertyValue("TopBorder", oLinBorda) oExtensao.setPropertyValue("RightBorder", oLinBorda) oExtensao.setPropertyValue("LeftBorder", oLinBorda) oExtensao.setPropertyValue("BottomBorder", oLinBorda) ' define e aplica uma TableBorder oLinBorda.OuterLineWidth = 100 oLinBorda.Color = CLng( "&HAABBCC" ) oBorda.TopLine = oLinBorda oBorda.BottomLine = oLinBorda oBorda.RightLine = oLinBorda oBorda.LeftLine = oLinBorda oBorda.IsTopLineValid = True oBorda.IsBottomLineValid = True oBorda.IsRightLineValid = True oBorda.IsLeftLineValid = True oExtensao.setPropertyValue("TableBorder", oBorda)
Inicialmente definimos as bordas de todas as clulas de oExtensao, depois aplicamos uma borda na extenso. Note os campos Is...Valid definidos como True.
Formatao Numrica
O OpenOffice.org possui diversas categorias de formatao numrica. Cada categoria possui vrios formatos pr-definidos. Atravs da interface com.sun.star.util.XNumberFormatsSupplier podemos ler, modificar e adicionar novos formatos aos nossos documentos. A interface XNumberFormatsSupplier contm os mtodos abaixo: getNumberFormats ( ) As Object < com.sun.star.util.XNumberFormats > getNumberFormatsSettings ( ) As Object < com.sun.star.beans.XPropertySet > Entre os mtodos da interface XNumberFormats, temos:
Introduo ao OpenOffice.org Basic 81
Documentos do Calc
Verso 2
getByKey (nChave As Long) As Object < XPropertySet > queryKeys (nCategoria As Long, nLocal As Long, bInserir As Boolean) As aVetor ( ) queryKey (sFormato As String, nLocal As Long, bProcura As Boolean) As Long addNew ( sFormato As String, nLocal As Long ) As Long A interface com.sun.star.util.XNumberFormatTypes contm mtodos para obter o ndice de alguns formatos pr-definidos. Aqui, usaremos o mtodo: getStandardFormat (nTipo AS Long, nLocal As Long) As Long O grupo de constantes com.sun.star.util.NumberFormat define valores para, dentre outras, as seguintes categorias: DATE, TIME, CURRENCY, NUMBER, DATETIME. O servio CellProperties contm a propriedade NumberFormat, que define o tipo formatao numrica de uma clula ou extenso de clulas. Vejamos um exemplo ilustrativo. Num documento do Calc, crie a macro abaixo, execute-a e observe o resultado.
Sub exibeFormatosNumericos Dim oDoc As Object Dim oFormatos As Object Dim mChaves As Variant Dim mProp As Variant Dim oLocal As New com.sun.star.lang.Locale oDoc = ThisComponent oFormatos = oDoc.getNumberFormats() oSettings = oDoc.getNumberFormatSettings() oInfo = oSettings.getPropertySetInfo() oProp = oInfo.getProperties() MsgBox UBound(oProp) For n = 0 To UBound(oProp) MsgBox oProp(n).Name Next n mChaves = oFormatos.queryKeys (0, oLocal, FALSE) MsgBox UBound(mChaves) mProp = oFormatos.getByKey(11).getPropertyValues() ' obtem os nomes das propriedades sMsg = "" For n=0 To UBound(mProp) sMsg = sMsg + mProp(n).Name + Chr$(13) Next n MsgBox sMsg ' exibe o valor de FormatString MsgBox mProp(0).Value End Sub
82
Verso 2
Documentos do Calc
Agora, vamos retornar nossa sub-rotina Sub editaPlanilha para aplicar formatao numrica em algumas clulas. Adicione o cdigo abaixo, execute e observe a sada:
' Formatos Numricos Dim oFormatos As Object Dim aLocal() As New com.sun.star.lang.Locale ' obtem os formatos numericos do modelo oFormatos = oDoc.getNumberFormats() ' obtm o ndice do formato padro para MOEDA
n%=oFormatos.getStandardFormat(com.sun.star.util.NumberFormat.CURRENCY,aLocal())
' obtem uma extenso de clulas oExtensao = oDoc.getSheets().getByIndex(0).getCellRangeByPosition(3,1,4,6) ' altera o formato padro para MOEDA oExtensao.NumberFormat = n% ' obtm uma clula e altera para MOEDA oCelula = oPlanilha.getCellByPosition(4, 7) oCelula.NumberFormat = n%
Note a declarao dos objetos, o uso do mtodo getStandardFormat () e o uso da propriedade NumberFormat para alterar a formatao das clulas.
Formatao Condicional
O servio com.sun.star.sheet.SheetCellRange contm as seguintes propriedades para formatao condicional: conditionalFormat - define condies para formatao condicional conditionalFormatLocal - define condies locais para formatao condicional A interface XSheetConditionalEntries prov os mtodos a seguir para operaes com as condies de formatao: addNew ( mCond () As < com.sun.star.beans.PropertyValue > ) o parmetro mCond um vetor com as seguintes entradas: - Operator com os possveis valores, definidos em com.sun.star.sheet.ConditionOperator NONE, EQUAL, NOT_EQUAL, GREATER, GREATER_EQUAL, LESS, LESS_EQUAL, BETWEEN, NOT_BETWEEN, FORMULA - Formula1 contendo uma cadeia com um valor ou frmula - Formula2 contendo um valor ou frmula, usada quando o operador for BETWEEN - StyleName contendo um nome de estilo de formatao de clula removeByIndex ( nIndice As Long ) remove a condio nIndice clear ( )
Introduo ao OpenOffice.org Basic 83
Documentos do Calc
Verso 2
limpa as condies atuais de formatao Acrescente o cdigo abaixo no final da Sub editaPlanilha, execute e observe a sada:
' FORMATAO CONDICIONAL ' Dim mCond (2) As New com.sun.star.beans.PropertyValue Dim oEntradas As Variant ' obtem uma extenso de clulas oExtensao = oDoc.getSheets().getByIndex(0).getCellRangeByPosition(4,1,4,6) ' obtm a formatao condicional corrente oEntradas = oExtensao.getPropertyValue("ConditionalFormat") ' define as propriedades de uma condio para formatao mCond(0).Name = "Operator" mCond(0).Value = com.sun.star.sheet.ConditionOperator.GREATER mCond(1).Name = "Formula1" mCond(1).Value = "500" mCond(2).Name = "StyleName" mCond(2).Value = "Result" ' limpa as condioes existentes oEntradas.clear() ' adiciona a nova condio oEntradas.addNew(mCond()) ' aplica a formatao condicional oExtensao.setPropertyValue("ConditionalFormat", oEntradas)
Neste cdigo, aplicamos o estilo Resultado se o valor da clula for maior que R$ 500,00. Podemos, tambm, aplicar estilos de formatao de clulas definidos pelos usurios.
84
Verso 2
Documentos do Calc
Descrio Se True, busca para o incio do documento Se True, localiza apenas as clulas com o texto e nada mais, seno localiza tambm as clulas onde o texto parte do contedo. Se True, busca por um estilo de clula
SearchStyles
Vejamos um exemplo de busca: crie um novo documento do Calc, preencha algumas clulas com o texto TOTAL e TOTAL GERAL, em seguida crie a macro abaixo e execute.
Sub buscaTexto Dim oDoc As Object Dim oDescBusca As Object Dim oPlanilha As Object oDoc = ThisComponent oPlanilha = oDoc.Sheets(0) oDescBusca = oPlanilha.createSearchDescriptor() oDescBusca.SearchWords = True oDescBusca.setSearchString ("TOTAL") oResultado = oPlanilha.findFirst( oDescBusca ) i = 0 Do Until IsNull(oResultado) oResultado.CharColor = RGB(250,100,50) oResultado = oPlanilha.findNext(oResultado, oDescBusca ) i = i + 1 Loop MsgBox "Ocorrncias de "+oDescBusca.getSearchString() + " " + Str$(i) End Sub
Agora, altere a propriedade SearchWords para False e execute novamente a macro observando o seu resultado. A substituio de texto implementada pela interface XReplaceable, que herda as caractersticas de XSearchable. Ela prov os mtodos: createReplaceDescriptor ( ) As Object <com.sun.star.util.XReplaceDescriptor> replaceAll ( xDescritor As Object <com.sun.star.util.XReplaceDescriptor>) As Long O servio ReplaceDescriptor tem mtodos para as propriedades da cadeia: getReplaceString ( ) As String setReplaceString ( sCadeia As String ) Eis uma busca e substituio simples, no mesmo documento do exemplo acima:
85
Documentos do Calc
Verso 2
Sub substituiTexto Dim oDoc As Object Dim oDescritor As Object Dim oPlanilha As Object oDoc = ThisComponent oPlanilha = oDoc.Sheets(0) oDescritor = oPlanilha.createReplaceDescriptor() oDescritor.setSearchString( "TOTAL GERAL" ) oDescritor.setReplaceString( "Total" ) n = oPlanilha.replaceAll(oDescritor) sMsg = oDescritor.getSearchString()+ por +oDescritor.getReplaceString() MsgBox sMsg + = + Str$(n) End Sub
Note que devemos executar a busca e a substituio numa extenso de clulas. Nos exemplos, utilizamos toda a planilha.
7.8 Ordenando
Para a ordenao de uma extenso de clulas, devemos utilizar os mesmos conceitos e servios j apresentados na seo Tabelas, do captulo sobre Documentos do Writer. Seguem, abaixo, os principais mtodos e propriedades utilizados nesta tarefa. Mtodos da interface com.sun.star.util.XSortable: createSortDescriptor ( ) As Variant <com.sun.star.beans.PropertyValue> sort (xDescritor As Variant <com.sun.star.beans.PropertyValue> ) Algumas das propriedades do descritor de ordenao (SortDescriptor): Propriedade IsCaseSensitive SortAscending SortColumns Descrio Se True, considera maisculas / minsculas Define a ordem da ordenao Se True ordena as colunas, seno ordena as linhas.
O servio com.sun.star.table.TableSortDescriptor inclui o servio SortDescriptor e possui as propriedades abaixo: Propriedade SortFields MaxFieldCount
86
Verso 2
Documentos do Calc
Orientation ContainsHeader
ordenao
No prximo bloco de cdigo, veremos a ordenao de uma extenso de clulas (A2:E7), do documento criado pela Sub editaPlanilha. Digite o cdigo abaixo no final da macro, execute e observe a saida.
' ================================= ' ORDENANDO UMA EXTENSO DE CLULAS ' ================================= Dim oCampoOrd(0) As New com.sun.star.util.SortField Dim oDescrOrd As Variant ' ' define a extenso a ser ordenada (A2:E7) oExtensao = oDoc.getSheets().getByIndex(0).getCellRangeByPosition(0,1,4,6) ' define o campo de ordenao e suas propriedades oCampoOrd(0).Field = 0 oCampoOrd(0).SortAscending = True oCampoOrd(0).FieldType = com.sun.star.util.SortFieldType.ALPHANUMERIC ' cria o descritor de ordenao oDescrOrd = oExtensao.createSortDescriptor() ' define as propriedades do descritor oDescrOrd(0).Name = "SortFields" oDescrOrd(0).Value = oCampoOrd() oDescrOrd(1).Name = "ContainsHeader" oDescrOrd(1).Value = False oDescrOrd(2).Name = "SortColumns" oDescrOrd(2).Value = False ' ordena a extenso oExtensao.sort(oDescrOrd())
Note que iniciamos com a declarao das variveis, criamos uma extenso de clulas com uma chamada ao mtodo getCellRangeByPosition (), definimos as propriedades do campo de ordenao, criamos o descritor e definimos as suas propriedades (o campo de ordenao uma propriedade do descritor) e, finalmente, invocamos o mtodo sort () para executar a sua tarefa.
Documentos do Calc
Verso 2
filter ( oDescritor As Object < XSheetFilterDescriptor > ) aplica o filtro na extenso de clulas O servio SheetFilterDescriptor controla as condies da operao de filtragem. Eis algumas de suas propriedades: IsCaseSensitive SkipDuplicates Orientation ContainsHeader CopyOutputData OutputPosition - se True, destingue maisculas e minsculas - seTrue, as entradas duplicadas sero excludas - filtra por Linhas ou Colunas ( TableOrientation ) - a primeira linha ou coluna um cabealho - se True, o resultado ser copiado para outro local - local da cpia ( estrutura CellAddress )
A interface XSheetFilterDescriptor contm os mtodos abaixo para obter e definir os campos com os critrios do filtro: getFilterFields ( ) aCampos () As Object < TableFilterField > retorna os campos com os critrios do filtro setFilterFields ( aCampos () As Object < TableFilterField > ) define os campos com os critrios do filtro A estrutura com.sun.star.table.TableFilterField contm os elementos a seguir: Connection Field Operator IsNumeric NumericValue StringValue - como ser a conexo com a condio anterior ( Or / And ) - a coluna usada na condio - operador condicional ( FilterOperator ) - se True, o valor do campo (Field) numrico - valor do campo, usar se IsNumeric for True - cadeia de caracteres, usar se IsNumeric for False
Os passos necessrios para filtrar dados numa planilha so: a) obter a extenso de clulas a ser filtrada; b) definir a estrutura dos campos com os critrios do filtro; c) criar e definir os dados do descritor do filtro; d) aplicar o filtro. Vejamos um trecho de cdigo fonte que aplica um filtro simples numa extenso de clulas.
Sub aplicaFiltro Dim oDoc As Object Dim oPlan As Object Dim oExt As Object
88
Verso 2
Documentos do Calc
Dim oDescFiltro As Variant Dim oCamposFiltro(0) As New com.sun.star.sheet.TableFilterField oDoc = ThisComponent oPlan = oDoc.getSheets().getByIndex(0) oExt = oPlan.getCellRangeByPosition(0,1,4,6) ' define a estrutura TableFilterField oCamposFiltro(0).Field = 4 oCamposFiltro(0).IsNumeric = True oCamposFiltro(0).Operator = com.sun.star.sheet.FilterOperator.GREATER_EQUAL oCamposFiltro(0).NumericValue = 300 ' cria o descritor do filtro vazio (True) oDescFiltro = oExt.createFilterDescriptor (True) ' define o campo de filtro oDescFiltro.setFilterFields (oCamposFiltro()) ' aplica o filtro oExt.filter (oDescFiltro) ' MsgBox "OK para filtrar Caracteres" ' redefine a estrutura TableFilterField oCamposFiltro(0).Field = 0 oCamposFiltro(0).IsNumeric = False oCamposFiltro(0).Operator = com.sun.star.sheet.FilterOperator.GREATER oCamposFiltro(0).StringValue = "A 1" ' cria um descritor de filtro vazio (True) oDescFiltro = oExt.createFilterDescriptor (True) ' define o campo de filtro oDescFiltro.setFilterFields (oCamposFiltro()) ' aplica o filtro oExt.filter (oDescFiltro) End Sub
Se voc quiser experimentar este cdigo, crie uma macro no documento gerado pela Sub editaPlanilha e execute, observando a sada. Note que a estrutura TableFilterField pode ter mais de um campo com critrios de filtragem. Tente acrescentar cdigo para copiar o resultado do filtro na Planilha2 do documento.
Documentos do Calc
Verso 2
remove os subtotais do objeto O servio SubTotalDescriptor uma representao de como os subtotais sero criados. A seguir, algumas de suas propriedades: InsertPageBreaks IsCaseSensitive EnableUserSortList UserSortListIndex EnableSort SortAscending - insere quebra de pgina aps cada subtotal - considera letras maisculas / minsculas - se True permite a definio de uma lista para ordenao - a lista para ordenao, se EnableUserSortList for True - define se o contedo dos campos sero ordenados - se True ordenao crescente (depende de EnableSort )
Alm das propriedades acima, o descritor deve conter os campos de subtotais. A interface XSubTotalDescriptor prov mtodos para adicionar ou limpar campos: addNew ( aColunas() As < SubTotalColumn >, nColGrupo As Long) adiciona os campos ao descritor, nColGrupo especifica a coluna base para agrupamento clear ( ) remove todos os campos de subtotais do objeto A estrutura com.sun.star.sheet.SubTotalColumn contm os elementos: Column Function - ndice da coluna a subtotalizar - o tipo de subtotal, definido em com.sun.star.sheet.GeneralFunction
Os passos necessrios para adicionar linhas com subtotais numa extenso de clulas so: a) obter a extenso de clulas a ser subtotalizada; b) definir a estrutura dos campos de subtotal; c) criar e definir os dados do descritor de subtotal; d) aplicar a operao de subtotal. Vejamos um trecho de cdigo fonte que aplica um subtotal numa extenso de clulas.
Sub aplicaSubTotal Dim oDoc As Object Dim oPlan As Object Dim oExt As Object Dim oDescSubTotal As Variant Dim oCamposSubTotal(0) As New com.sun.star.sheet.SubTotalColumn oDoc = ThisComponent oPlan = oDoc.getSheets().getByIndex(0) oExt = oPlan.getCellRangeByPosition(0,0,4,6) ' define a estrutura SubTotalColumn oCamposSubTotal(0).Column = 4
90
Verso 2
Documentos do Calc
oCamposSubTotal(0).Function = com.sun.star.sheet.GeneralFunction.SUM ' cria o descritor do subtotal oDescSubTotal = oExt.createSubTotalDescriptor (True) ' adiciona o campo subtotal e a coluna base oDescSubTotal.addNew (oCamposSubTotal(), 0) ' aplica o subtotal oExt.applySubTotals(oDescSubTotal, True) End Sub
Se voc quiser experimentar este cdigo, crie uma macro no documento gerado pela Sub editaPlanilha, execute e analise o resultado.
7.11 Grficos
Um grfico um documento embutido num outro documento do OpenOffice.org. A API do OpenOffice.org contm diversos servios e interfaces para a gerao de grficos, a partir dos dados contidos numa planilha. O servio com.sun.star.table.TableCharts suporta os mtodos das interfaces XTableCharts, XIndexAccess e XEnumerationAccess. Mtodos da interface com.sun.star.table.XTableCharts: addNewByName ( sNome As String, oArea As Object < com.sun.star.awt.Rectangle >, oExt ( ) As Object < com.sun.star.table.CellRangeAddress >, bTitCol As Boolean, bTitLin As Boolean ) Adiciona o grfico na coleo de grficos da planilha. Os seus parmetros so: sNome oArea oExt bTitCol bTitLin - o nome do grfico - a rea (retngulo) aonde o grfico ser plotado - a extenso de clulas com os dados - se True, os dados da linha superior sero usados na legenda do grfico - se True, os dados da primeira coluna sero usados como ttulos no eixo
removeByName ( sNome As String ) remove o grfico com o nome sNome da coleo. O servio com.sun.star.table.TableChart suporta a interface XTableChart com os mtodos: getHasColumnHeaders ( ) As Boolean setHasColumnHeaders ( bTituloColuna As Boolean ) getHasRowHeaders ( ) As Boolean setHasRowHeaders ( bTituloColuna As Boolean ) getRanges ( ) As sExtensoes ( ) < CellRangeAddress >
Introduo ao OpenOffice.org Basic 91
Documentos do Calc
Verso 2
setRanges ( sExtensoes ( ) As Object < CellRangeAddress > ) Um documento grfico contm uma referncia para uma fonte de dados, um diagrama e algumas propriedades como ttulo, sub-ttulo e legenda. O servio ChartDocument o modelo do documento grfico e suporta as interfaces XChartDocument, XPropertySet e XMultiServiceFactory . Ele possui as seguintes propriedades: HasMainTitle HasSubTitle HasLegend - Se True, exibe o ttulo principal - Se True, exibe o subttulo - Se True, exibe a legenda
A interface com.sun.star.chart.XChartDocument prov os mtodos: getTitle ( ) As < com.sun.star.drawing.XShape > getSubTitle ( ) As < com.sun.star.drawing.XShape > getLegend ( ) As < com.sun.star.drawing.XShape > getArea ( ) As < com.sun.star.beans.XPropertySet > getDiagram ( ) As < com.sun.star.chart.XDiagram > setDiagram ( oDiagrama As < com.sun.star.chart.XDiagram >) getData ( ) As < com.sun.star.chart.XChartData > attachData ( oDadosExternos As < com.sun.star.chart.XChartData >) O diagrama o objeto que contm a forma do grfico, baseada no servio Diagram e suas interfaces XDiagram e XPropertySet. Diferentes tipos de diagramas podem ser criados com o mtodo createInstance (), da interface XMultiServiceFactory. Eis alguns servios para tipos de diagramas: com.sun.star.chart.BarDiagram com.sun.star.chart.LineDiagram com.sun.star.chart.PieDiagram com.sun.star.chart.AreaDiagram com.sun.star.chart.XYDiagram Podemos alterar a propriedade Diagram de um grfico com o cdigo a seguir:
oDiagrama = oGraf.createInstance("com.sun.star.chart.PieDiagram") oGraf.setDiagram ( oDiagrama )
Verso 2
Documentos do Calc
DataCaption
Para criar um grfico devemos seguir os passos abaixo: a) definir os dados a serem exibidos no grfico; b) definir a rea retangular aonde o grfico ser desenhado; c) adicionar o grfico coleo; d) recuperar o objeto grfico embutido. e) definir as propriedades do grfico. Vejamos um exemplo simples. Digite a macro a seguir e execute para ver a sada:
Sub criaGrafico Dim oDesk As Variant Dim oDoc As Object Dim mProp() As Variant Dim sURL As String ' cria documento do Calc oDesk = createUnoService("com.sun.star.frame.Desktop") sUrl = "private:factory/scalc" oDoc = oDesk.LoadComponentFromURL(sUrl, "_blank", 0, mProp()) ' edita clulas da planilha Dim oPlanilha As Object Dim oCelula As Object Dim sTitCol() As String ' escreve os titulos das colunas sTitCol = Array ("Perodo","Computador","Perifrico","Servio","Total") oPlanilha = oDoc.getSheets().getByIndex(0) For i% = 0 To 4 oCelula = oPlanilha.getCellByPosition(i%, 0) oCelula.setString(sTitCol(i%)) Next i% ' preenche as clulas com texto, valor e formula For i% = 1 To 4 For j% = 0 To 4 oCelula = oPlanilha.getCellByPosition(j%, i%) If (j% = 0) Then oCelula.setString(Str$(i%) + " Trim") ElseIf (j% > 0 And j < 4) Then oCelula.setValue(1000 * Rnd()) Else sExt = "B" + Trim$(Str$(i%+1)) + ":" + "D" + Trim$(Str$(i%+1)) sFormula = "=Soma(" + sExt + ")" oCelula.FormulaLocal = sFormula End If Next j% Next i% ' ' insere um grfico de colunas Dim oRet As New com.sun.star.awt.Rectangle Dim oEndExt(0) As New com.sun.star.table.CellRangeAddress Dim oGraficos As Object ' define o nome do grfico sNome = "Trimestral" ' define o endereo da extenso de clulas com os dados oEndExt(0).Sheet = 0
93
Documentos do Calc
Verso 2
oEndExt(0).StartColumn = 0 oEndExt(0).StartRow = 0 oEndExt(0).EndColumn = 3 oEndExt(0).EndRow = 4 ' define a rea do grfico oRet.X = 1000 oRet.Y = 3000 oRet.Width = 12000 oRet.Height = 12000 ' obtm a coleo de grficos da Planilha1 oGraficos = oPlanilha.Charts ' adiciona um grfico coleo oGraficos.addNewByName(sNome, oRet, oEndExt(), True, True) ' define as propriedades(Titulo) oGraf = oGraficos.getByName(sNome).getEmbeddedObject() oGraf.Title.String = "Faturamento Trimestral" oGraf.HasSubTitle = True oGraf.SubTitle.String = "Ano 2003" End Sub
Comeamos preenchendo as clulas com os dados, depois, definimos o nome do grfico, a extenso de clulas com os dados e a rea (retngulo) aonde o grfico ser plotado. Aps estes passos preliminares, obtemos a coleo dos grficos da planilha e adicionamos o nosso grfico na coleo, com uma chamada ao mtodo addNewByName ( ). Finalmente, obtemos o objeto grfico embutido, com uma chamada ao mtodo getByName ( ) associada ao mtodo getEmbeddedObject ( ) e, ento, alteramos algumas propriedades do grfico. Aproveitando o exemplo acima, vamos mostrar como alterar a propriedade Diagram de um grfico. Acrescente o cdigo fonte abaixo ao final da Sub criaGrafico e execute para criar um grfico do tipo Pizza, representando os dados da linha 2 da planilha.
' Criando um grfico do tipo Pizza Dim oExtPizza(1) As New com.sun.star.table.CellRangeAddress ' MsgBox "OK para uma Pizza" ' remove o grfico de barras oGraficos.removeByName(sNome) sNome = "GrafPizza" ' define o endereo da extenso de clulas com legendas oExtPizza(0).Sheet = 0 oExtPizza(0).StartColumn = 0 oExtPizza(0).StartRow = 0 oExtPizza(0).EndColumn = 3 oExtPizza(0).EndRow = 0 ' define o endereo da extenso de clulas com dados oExtPizza(1).Sheet = 0 oExtPizza(1).StartColumn = 0 oExtPizza(1).StartRow = 1 oExtPizza(1).EndColumn = 3 oExtPizza(1).EndRow = 1 ' adiciona um grfico coleo oGraficos.addNewByName(sNome, oRet, oExtPizza(), True, True) ' define as propriedades
94
Verso 2
Documentos do Calc
oGraf = oGraficos.getByName(sNome).getEmbeddedObject() oGraf.Diagram = oGraf.createInstance("com.sun.star.chart.PieDiagram") oGraf.Diagram.DataRowSource = com.sun.star.chart.ChartDataRowSource.ROWS oGraf.Title.String = "1 Trimestre 2003"
Observe que temos um vetor de estruturas CellRangeAddress, onde o primeiro elemento contm os dados da legenda do grfico e o segundo os dados a serem representados. Note tambm a mudana da propriedade Diagram com uma chamada ao mtodo createInstance ( ) e a mudana da propriedade DataRowSource do diagrama. Note, ainda, que o fato de podermos definir um vetor CellRangeAddress, indica que podemos ter extenses de clulas, consecutivas ou no, contendo os dados a serem representados graficamente.
Ttulo do dilogo da seleo Se True encerra a seleo aps a liberao do boto do mouse
A interface com.sun.star.sheet.XRangeSelection prov os seguintes mtodos: startRangeSelection ( aProp () As Object < com.sun.star.beans.PropertyValue > ) inicia o processo de seleo da extenso de clulas abortRangeSelection ( ) aborta o processo de seleo addRangeSelectionListener( oList As < com.sun.star.sheet.XRangeSelectionListener>) adiciona um listener para monitorar o trmino ou o cancelamento da seleo removeRangeSelectionListener( oList As < com.sun.star.sheet.XRangeSelectionListener>) remove o listener especificado no parmetro addRangeSelectionChangeListener( oList As < XRangeSelectionChangeListener >) adiciona um listener para monitorar mudanas durante a seleo removeRangeSelectionChangeListener ( oList As < XRangeSelectionChangeListener >)
Introduo ao OpenOffice.org Basic 95
Documentos do Calc
Verso 2
remove o listener de mudanas especificado no parmetro A interface com.sun.star.sheet.XRangeSelectionListener especifica os mtodos abaixo, a serem definidos pelo usurio, usando o Basic: done ( aEvento As < com.sun.star.sheet.RangeSelectionEvent > ) contm o cdigo a ser executado aps o trmino da seleo aborted ( aEvento As < com.sun.star.sheet.RangeSelectionEvent > ) contm o cdigo a ser executado aps o cancelamento da seleo A estrutura com.sun.star.sheet.RangeSelectionEvent contm o elemento RangeDescriptor, que uma representao textual da extenso de clulas selecionadas. Devemos criar uma instncia do listener chamando a funo createUnoService ( ) do OpenOffice.org Basic, eis a sua sintaxe: createUnoService ( sPrefixo As String, sListener As String ) As Object sPrefixo: o prefixo usado no nome dos mtodos do listener. O caractere sublinhado deve ser o ltimo do prefixo ( ex: listen_ ). sListener: o nome da interface do listener retorna um objeto listener, cujos mtodos podem ser usados na macro. Bem, j temos todas as ferramentas necessrias para executar a nossa tarefa. Vejamos como us-las atravs de um exemplo simples de seleo. Abra uma nova planilha e salve-a, em seguida crie um novo mdulo para a macro, isto porque usamos variveis Pblicas em nossa macro. Finalmente, digite o cdigo fonte abaixo (ou copie e cole) no novo mdulo. Ative a planilha e execute a macro, surge uma caixa de dilogo solicitando a seleo da extenso, use o mouse ou o teclado para selecionar. Aps a seleo, a propriedade CharHeight da extenso ser alterada.
' ' seleo de uma extenso durante a execuo da macro ' usando XRangeSelectionListener ' Public aListener As Object Public aResult As String Public bSelecao As Boolean Sub Main ' Dim oDoc As Object Dim oDocView As Object Dim oPlan As Object Dim aProp(2) As New com.sun.star.beans.PropertyValue ' oDoc = ThisComponent oDocView = oDoc.getCurrentController() ' define um ouvinte (listener) Set aListener = CreateUnoListener("oList_", _
96
Verso 2
Documentos do Calc
"com.sun.star.sheet.XRangeSelectionListener") ' adiciona o ouvinte oDocView.addRangeSelectionListener ( aListener ) ' define as propriedades para a seleo aProp(0).Name = "InitialValue" aProp(0).Value = "" '"$Planilha1.$A$1:$B$2" aProp(1).Name = "Title" aProp(1).Value = "Selecione a " aProp(2).Name = "CloseOnMouseRelease" aProp(2).Value = True ' inicia o processo de seleo bSelecao = False oDocView.startRangeSelection ( aProp () ) Do While ( bSelecao = False) ' aguarda a seleo Loop ' remove o ouvinte (listener) oDocView.removeRangeSelectionListener(aListener) ' opera sobre o resultado da seleo If ( bSelecao = True And Len (aResult) > 0 ) Then MsgBox aResult oPlan = oDocView.getActiveSheet() oRange = oPlan.getCellRangeByName(aResult) oRange.CharHeight = 20 Else MsgBox "Seleo recusada" End If ' End Sub ' Mtodos da interface com.sun.star.sheet.XRangeSelectionListener ' done ( ) Sub oList_done ( oEvent ) ' obtem o nome da extenso aResult = oEvent.RangeDescriptor bSelecao = True End Sub ' aborted ( ) Sub oList_aborted ( oEvent ) bSelecao = True End Sub Sub oList_disposing () ' implementao mnima End Sub
Inicialmente definimos algumas variveis pblicas, depois obtemos a vista do documento, pois a seleo ocorre na vista e chamamos a funo createUnoListener para criar uma instncia da interface XRangeSelectionListener, note o prefixo com o sublinhado no final. Aps a criao, registramos o listener com addRangeSelectionListener, como se estivessemos dizendo ao OpenOffice.org: ei, temos um novo monitor de seleo para a vista deste documento.
Introduo ao OpenOffice.org Basic 97
Documentos do Calc
Verso 2
Definimos ento, as propriedades iniciais para a nossa seleo, note que o valor da propriedade CloseOnMouseRelease True, e atribuimos o valor False para o sinalizador bSelecao. Depois, chamamos o mtodo startRangeSelection passando o vetor com as propriedades iniciais. A seguir, no lao Do While ... Loop, aguardamos a seleo do usurio. A macro s abandona o lao quando o valor de bSelecao for True. Isto s acontece nos mtodos done () e aborted () do listener. Estes mtodos so chamados automaticamente pelo OpenOffice.org no final ou no cancelamento da seleo, isto , quando o usurio completar a seleo, liberando o boto do mouse ou quando ele fechar o dilogo de seleo. Terminada a seleo, removemos o listener com o mtodo removeRangeSelectionListener e, finalmente, processamos o resultado da nossa seleo. Alm da sub-rotina Main, temos, em nossa macro, as sub-rotinas abaixo: Sub oList_done ( oEvent ) Sub oList_aborted ( oEvent ) Sub oList_disposing ( ) - corresponde ao mtodo done ( ) da interface - corresponde ao mtodo aborted ( ) da interface - chamada na remoo do listener
Na sub-rotina done ( ), atribuimos a descrio textual da seleo varivel pblica aResult, atravs do elemento RangeDescriptor da estrutura oEvent, e, depois, definimos o nosso sinalizador bSelecao para True. Na sub-rotina aborted ( ), apenas definimos o nosso sinalizador bSelecao para True. Note o uso do prefixo de createUnoListener antecedendo os nomes dos mtodos da interface. A API do OpenOffice.org contm muitas interfaces que usam listeners. muito importante que todos os mtodos da interface sejam implementados com o Basic. Quando nenhuma ao for necessria, faa uma implementao mnima, como em oList_disposing ( ).
- nenhuma clula ser movida - as clulas abaixo das clulas inseridas so movidas para baixo - as clulas direita das clulas inseridas so movidas para a direita - as linhas abaixo das clulas inseridas so movidas para baixo
Introduo ao OpenOffice.org Basic
Verso 2
Documentos do Calc
COLUMNS - as colunas direita das clulas inseridas so movidas para a direita estas constantes definem o deslocamento das clulas adjacentes. copyRange (mDest As < com.sun.star.table.CellAddress >, mOrig As < com.sun.star.table.CellRangeAddress > ) copia o grupo de clulas de mOrig para mDest no mesmo documento. moveRange ( mDest As < com.sun.star.table.CellAddress >, mOrig As < com.sun.star.table.CellRangeAddress > ) move o grupo de clulas mOrig para mDest, o contedo de mOrig apagado. removeRange ( mEndereco As < com.sun.star.table.CellRangeAddress >, nModo As Integer ) remove o grupo de clulas de mEndereco; os valores de nModo esto definidos na enumerao < com.sun.star.sheet.CellDeleteMode >: NONE - nenhuma clula ser movida UP - as clulas abaixo das clulas apagadas so movidas para cima LEFT - as clulas direita das clulas apagadas so movidas para a esquerda ROWS - as linhas abaixo das clulas apagadas so movidas para cima COLUMNS - as colunas direita das clulas apagadas so movidas para a esquerda estas constantes definem o deslocamento das clulas adjacentes. Agora, um exemplo simples para demonstrar o emprego destes componentes da API.
Sub copiaExtensao ' exemplo interface sheet.XCellRangeMovement Dim oDoc As Object Dim oPlan As Object Dim oExt As Object Dim mDest As New com.sun.star.table.CellAddress Dim mEnd As New com.sun.star.table.CellRangeAddress oDoc = ThisComponent oExt = oDoc.getCurrentSelection() oPlan = oExt.getSpreadsheet() mEnd = oExt.getRangeAddress() mDest.Sheet = 1 ' Planilha2 mDest.Column = 0 mDest.Row = 0 ' copyRange copia tambm a formatao da clula oPlan.copyRange(mDest, mEnd) ' End Sub
Aqui, obtemos a seleo corrente e copiamos para a Planilha2, tendo como origem a clula A1. Observe que o mtodo copyRange chamado a partir do objeto Spreadsheet.
99
Documentos do Calc
Verso 2
Vnculos
O servio < com.sun.star.sheet.SpreadsheetDocument > contm as propriedades abaixo, relacionadas com vnculos noutros documentos: SheetLinks - contm a coleo de vnculos de planilhas no documento AreaLinks - contm a coleo de vnculos de reas no documento DDELinks - contm a coleo de vnculos DDE do documento Estas colees podem ser obtidas como abaixo:
oDoc = ThisComponent oVinculos = oDoc.SheetLinks documento ' obtm os vnculos de planilha do
A interface < com.sun.star.sheet.XSheetLinkable > possui os seguintes mtodos para definir vnculos com planilhas de outros documentos: getLinkMode ( ) As < com.sun.star.sheet.SheetLinkMode > setLinkMode ( nModo As < com.sun.star.sheet.SheetLinkMode > ) obtm ou define o modo do vnculo getLinkUrl ( ) As String setLinkUrl ( sURL As String ) obtm ou define a URL do recurso ( o documento vinculado ) getLinkSheetName ( ) As String setLinkSheetName ( sPlanilha As String ) obtm ou define o nome da planilha dentro do documento vinculado link ( sURL As String, sPlanilha As String, sFiltro As String, sOpcoes As String, nModo As < com.sun.star.sheet.SheetLinkMode > ) cria um vnculo com uma planilha, em outro documento, se ele no existir Os valores possveis para LinkMode, esto em < com.sun.star.sheet.SheetLinkMode >: NONE - sem vnculo NORMAL - copia os valores e as frmulas
100 Introduo ao OpenOffice.org Basic
Verso 2
Documentos do Calc
VALUE
Eis alguns nomes de filtros do OpenOffice.org: StarOffice XML (Calc) - documentos do Calc no formato XML MS Excel 97 - documentos do Excel 97/2000/XP MS Excel 95 - documentos do Excel 5.0 / 95 Para estes filtros, podemos passar uma cadeia vazia como opo do filtro. Vejamos um exemplo:
Sub vinculoPlanilha ' Dim oDoc As Object Dim oPlan As Object ' oDoc = ThisComponent oPlan = oDoc.Sheets(0) ' edite sURL para seu sistema: sURL = "file:///d:/nad/openoffice/Intro_OOo_Basic/novo_mat/editaPlan.sxc" sOrigem = "Planilha1" sFiltro = "StarOffice XML (Calc)" sOpcoes = "" ' define o modo nModo = com.sun.star.sheet.SheetLinkMode.NORMAL ' estabelece o vnculo oPlan.link(sURL, sOrigem, sFiltro, sOpcoes, nModo) ' desativa o vnculo oPlan.setLinkMode(com.sun.star.sheet.SheetLinkMode.NONE) ' End Sub
Note que definimos os parmetros e estabelecemos o vnculo. Aps executar esta macro, a planilha vinculada ser carregada para o documento. Alm de planilhas, possvel vincular uma ou mais reas de um documento externo a um outro documento. A principal interface usada para isto, < com.sun.star.sheet.XAreaLinks >, tem os mtodos: insertAtPosition ( aPos As <com.sun.star.table.CellAddress >, sArq As String, sFonte As String , sFiltro As String, sFiltroOp As String ) insere uma rea vnculada na coleo. Os parmetros tem os significados: aPos posio da clula inicial no documento de destino (estrutura). sArq Url do recurso (documento de origem). sFonte endereo da rea no documento de origem (por ex: Planilha1.A1:D10). sFiltro nome do filtro usado para converter os dados. sFiltroOp opes para o filtro as opes de filtro so especficas para alguns tipos de filtro.
101
Documentos do Calc
Verso 2
removeByIndex ( nIndex ) remove a rea vinculada da coleo. Vamos apresentar um exemplo simples, demonstrando esta possibilidade:
Sub vinculoArea ' Dim oDoc As Object Dim oPlan As Object Dim oLinks As Object Dim aPos As New com.sun.star.table.CellAddress oDoc = ThisComponent oPlan = oDoc.Sheets(1) sURL = "file:///d:/nad/openoffice/Intro_OOo_Basic/novo_mat/editaPlan.sxc" sFonte = "Planilha1.A1:E8" sFiltro = "StarOffice XML (Calc)" sOpcoes = "" ' define a origem da rea no destino aPos.Sheet = 1 aPos.Column = 0 aPos.Row = 0 ' obtm coleo oLinks = oDoc.AreaLinks ' insere um vnculo com a rea sFonte oLinks.insertAtPosition(aPos, sURL, sFonte, sFiltro, sOpcoes) 'remove o ultimo link oLinks.removeByIndex(oLinks.Count - 1) ' End Sub
Inicialmente definimos os parmetros, depois obtemos a coleo de vnculos, adicionamos o novo vnculo e, por fim, removemos o vnculo. Se um vnculo permanecer ativo, na prxima carga do documento destino, o operador ser informado da sua existncia e questionado se deseja, ou no, atualiz-los.
102
Verso 2
Documentos do Calc
doImport ( oDescritor ( ) As < com.sun.star.beans.PropertyValue > ) importa os dados conforme o descritor O servio com.sun.star.sheet.DatabaseImportDescriptor possui as propriedades abaixo: Propriedade SourceType DatabaseName SourceObject Descrio Tipo da (com.sun.star.sheet.DataImportMode) fonte
Cadeia com o nome da fonte de dados registrada no OOo Cadeia com o nome do objeto dentro da fonte de dados
Os valores possveis para SourceType so (com.sun.star.sheet.DataImportMode): NONE SQL TABLE QUERY - nada ser importado - um comando SQL ser passado para SourceObject - o nome de uma tabela ser passado para SourceObject - o nome de uma consulta da fonte de dados ser passado para SourceObject
Agora um exemplo. A macro abaixo importa todos os registros resultantes do comando SQL para uma planilha.
Sub importaDadosParaPlanilha ' Dim oCelOrigem As Object Dim oDescritor As Variant Dim sFonteDados As String Dim sOrigemDados As String Dim iTipo As Long ' obtem a clula da origem na planilha oCelOrigem = ThisComponent.Sheets(1).getCellByPosition(0,0) ' cria um descritor de importao oDescritor = oCelOrigem.createImportDescriptor(True) ' inicializa variveis iTipo = com.sun.star.sheet.DataImportMode.SQL sFonteDados = "Bibliography" sOrigemDados = "Select * From biblio" ' define as propriedades do descritor oDescritor(0).Name = "DatabaseName" oDescritor(0).Value = sFonteDados oDescritor(1).Name = "SourceType" oDescritor(1).Value = iTipo oDescritor(2).Name = "SourceObject" oDescritor(2).Value = sOrigemDados ' importa os dados oCelOrigem.doImport(oDescritor()) ' End Sub
103
Documentos do Calc
Verso 2
Como exerccio, altere os valores das variveis oCelOrigem, iTipo e sOrigemDados, executando novamente a macro.
104
Verso 2
Banco de Dados
8 Banco de Dados
8.1 Introduo
O OpenOffice.org traz um poderoso sistema de conexo com banco de dados. O seu principal objetivo oferecer uma independncia de plataforma, permitindo o acesso a banco de dados de diversos fabricantes. O mecanismo que o OpenOffice.org usa para atingir o seu objetivo chamado SDBC (Star Database Connectivity), que permite a escrita de drivers SDBC especficos para diferentes fontes de dados. Estes drivers podem, inclusive, usar padres de acesso a dados bem estabelecidos, como ODBC e JDBC. Deste modo, qualquer banco de dados que suporte um dos padres acima, pode ser definido como uma fonte de dados para o OpenOffice.org. O OpenOffice.org tambm acessa, nativamente, tabelas do Dbase e Planilhas do Calc, como fonte de dados. Dentre as facilidades de acesso a banco de dados do OpenOffice.org podemos citar: o uso da SQL (Linguagem de Consulta Estruturada) para consultas e o uso de vnculos e formulrios baseados em documentos do OpenOffice.org. Se voc no tem experincia com banco de dados, antes de continuar, procure se familiarizar com as ferramentas grficas do OpenOffice.org para acesso a fonte de dados. Selecione Ver Navegador Fonte de Dados. Nesta janela, podemos selecionar uma fonte de dados registrada e operar sobre suas tabelas, consultas e vnculos. Para administrar as fontes de dados, selecione Ferramentas Fonte de Dados.
Banco de Dados
Verso 2
Os principais servios e interfaces da API do OpenOffice.org, relacionados com banco de dados esto agrupados nos mdulos: com.sun.star.sdb - com.sun.star.sdbcx - com.sun.star.sdbc Vejamos alguns servios, relacionados com as fontes de dados. O ponto de entrada o contexto de banco de dados, representado pelo servio com.sun.star.sdb.DatabaseContext. Para criar um objeto DatabaseContext, chamamos a funo createUnoService ( ): oContexto = createUnoService ( com.sun.star.sdb.DatabaseContext ) Podemos obter as fontes de dados registradas, usando os mtodos relacionados com as interfaces XNameAccess e XEnumeration, eis alguns deles: hasByName ( sNome As String ) As Boolean getByName ( sNome As String ) As Variant getElementNames ( ) As String ( ) hasElements ( ) As Boolean hasMoreElements ( ) As Boolean nextElement ( ) As Variant Lembre-se que, antes de usar os mtodos de XEnumeration, uma enumerao deve ser criada com uma chamada ao mtodo createEnumeration ( ). J temos as ferramentas necessrias para escrever um exemplo. Vamos exibir os nomes das fontes de dados registradas em nosso contexto de banco de dados. Digite a Sub contextoBancoDados, abaixo, e execute para ver o resultado.
Sub contextoBancoDados ' Dim oContexto As Variant Dim sNomes() As String ' ' cria o contexto de banco de dados oContexto = createUnoService("com.sun.star.sdb.DatabaseContext") If oContexto.hasElements() Then ' obtem os nomes das fontes de dados sNomes = oContexto.getElementNames() ' exibe os nomes das fontes de dados sMsg = "" For i = LBound(sNomes) to UBound(sNomes) sMsg = sMsg + sNomes(i) + Chr$(13) Next i MsgBox sMsg Else MsgBox "Nenhuma fonte registrada"
106
Verso 2
Banco de Dados
Outro servio da linha de frente com.sun.star.sdb.DataSource, que representa um objeto fonte de dados. Ele tem vrias propriedades e oferece diversas interfaces. Antes de adicionar uma nova fonte de dados ao contexto, precisamos criar um objeto DataSource. Isto pode ser feito de duas maneiras: oFonte = oDataContext.createInstance ( ) ' em desuso oFonte = createUnoService ( com.sun.star.sdb.DataSource ) Para obter, apagar ou registrar uma fonte de dados no contexto de banco de dados, devemos usar os mtodos da interface com.sun.star.uno.XNamingService do objeto DatabaseContext. getRegisteredObject ( sNome As String ) As < com.sun.star.uno.XInterface > retorna o objeto fonte de dados com o nome sNome registerObject ( sNome As String, oFonte As < com.sun.star.uno.XInterface >) registra o objeto oFonte como uma fonte de dados com o nome sNome revokeObject ( sNome As String ) revoga a fonte de dados com o nome sNome Eis algumas das propriedades do servio com.sun.star.sdb.DataSource: Propriedade Name URL User Password IsPasswordRequire d IsReadOnly Descrio Nome da fonte de dados URL do banco de dados (sdbc:subprotocolo:subname ou jdbc ...) Nome de login do usurio Senha do usurio Se True, uma senha ser necessria Se True, acesso somente para leitura
Vamos retomar o nosso exemplo e acrescentar cdigo para adicionar uma nova fonte de dados ao contexto de banco de dados. Acrescente o cdigo abaixo na Sub contextoBancoDados, execute a macro e verifique, atravs de Ferramentas Fonte de Dados, se a nova fonte foi criada.
107
Banco de Dados
Verso 2
' ADICIONA UMA NOVA FONTE DE DADOS Dim oFonte As Variant ' cria uma instancia de fonte de dados oFonte = createUnoService("com.sun.star.sdb.DataSource") ' oFonte = oContexto.createInstance() ' testa se a fonte j est registrada If oContexto.hasByName("Minha_Fonte") Then MsgBox "Minha_Fonte j registrada!" Exit Sub Else ' registra a nova fonte no contexto oContexto.registerObject("Minha_Fonte", oFonte) ' define a propriedade URL >>>> ALTERE PARA O SEU SISTEMA <<<< oFonte.setPropertyValue("URL", _ "sdbc:dbase:file:///D:/NAD/OPENOFFICE/BDados") End If
O objeto DataSource suporta algumas interfaces relacionadas com os tipos bsicos de informaes da fonte de dados, seguem as principais: A interface com.sun.star.util.XFlushable, relacionada com o fluxo de dados entre o objeto e o banco de dados, contendo os mtodos: flush ( ) encaminha os dados do objeto conectado para o banco de dados addFlushListener ( ) removeFlushListener ( ) adiciona e remove listeners para o evento flushed A interface com.sun.star.sdb.XQueryDefinitionsSupplier, com o mtodo: getQueryDefinitions ( ) As < com.sun.star.container.XNameAccess > retorna o recipiente com as consultas definidas numa fonte de dados. Atravs da interface com.sun.star.sdb.XBookmarksSupplier, podemos obter os vnculos dos documentos associados a uma fonte de dados, com uma chamada ao mtodo: getBookmarks ( ) As < com.sun.star.container.XNameAccess > retorna uma coleo de cadeias com a localizao dos documentos vinculados. Vamos obter a nossa recm-criada fonte de dados e fazer algumas verificaes. Crie a subrotina Sub infoFonteDados e execute, observando a sada.
Sub infoFonteDados ' Dim oContexto As Variant Dim oFonte As Variant Dim oConsultas As Object Dim oVinculos As Object Dim sNomes() As String
108
Verso 2
Banco de Dados
' ' cria o contexto de banco de dados oContexto = createUnoService("com.sun.star.sdb.DatabaseContext") ' obtem o objeto fonte de dados oFonte = oContexto.getRegisteredObject("Minha_Fonte") ' ' obtem a propriedade TableFilter sMsg = "Tabelas: " + Chr$(10) sNomes = oFonte.getPropertyValue("TableFilter") If UBound(sNomes) > 0 Then For i = 0 To UBound(sNomes) sMsg = sMsg + sNomes (i) + Chr$(10) Next i MsgBox sMsg Else MsgBox "Nenhuma Tabela para visualizar" End If ' ' verifica consultas oConsultas = oFonte.getQueryDefinitions() If oConsultas.getCount() > 0 Then MsgBox Str$(oConsultas.getCount()) + " consultas definidas" Else MsgBox "Nenhuma consulta definida." End If ' ' verifica vnculos oVinculos = oFonte.getBookmarks() If oVinculos.getCount() > 0 Then MsgBox Str$(oVinculos.getCount()) + " vnculos definidos" Else MsgBox "Nenhum vnculo definido." End If ' End Sub
Note que as tabelas a serem visualizadas pela fonte de dados uma propriedade de DataSource, enquanto as consultas e vnculos so obtidos atravs de mtodos especficos.
8.3 Conexes
At o momento, trabalhamos dentro do contexto de banco de dados. Se a nossa tarefa estiver relacionada com os dados armazenados no banco de dados ou com a sua estrutura, devemos estabelecer uma conexo com o mesmo. Uma conexo um canal de comunicao entre o usurio e o banco de dados, permitindo a transferncia de dados entre eles. Este o principal objetivo do servio DataSource e, para isto, dispe das seguintes interfaces e mtodos: A interface com.sun.star.sdb.XCompletedConnection, possui o mtodo:
109
Banco de Dados
Verso 2
connectWithCompletion ( oManip As < com.sun.star.task.XInteractionHandler > ) As <com.sun.star.sdbc.XConnection> tenta estabelecer uma conexo com o banco de dados, se necessrio, solicita informaes. A interface com.sun.star.sdbc.XDataSource, tem os seguintes mtodos: getConnection( sUser As String, sSenha As String) As < com.sun.star.sdbc.XConnection > tenta estabelecer uma conexo com o banco de dados. setLoginTimeout ( iSegundos As Long) define o perodo, em segundos, para tentar estabelecer a conexo getLoginTimeout ( ) As Long obtm o perodo, em segundos, para tentar de estabelecer a conexo Os mtodos connectWithCompletion () e getConnection () retornam um objeto, que representa uma conexo. Este objeto, por sua vez, suporta outros servios e interfaces. Uma das principais interfaces do servio com.sun.star.sdb.Connection XConnection, com mtodos para diversas operaes. A seguir, alguns deles: setAutoCommit ( bSinal As Boolean ) getAutoCommit ( ) As Boolean commit ( ) rollback ( ) isClosed ( ) As Boolean getMetaData ( ) As < com.sun.star.sdbc.XDatabaseMetaData > setReadOnly ( sSinal As Boolean ) isReadOnly ( ) As Boolean A interface com.sun.star.sdbc.XDatabaseMetaData, retornada por getMetaData ( ), define vrios mtodos para obter informaes sobre o banco de dados e sua estrutura. Seguem alguns: getUserName ( ) As String getDatabaseProductName ( ) As String getDriverName ( ) As String getTables ( ) As < com.sun.star.sdbc.XResultSet > getColumns ( ) As < com.sun.star.sdbc.XResultSet > getNumericFunctions ( ) As String getStringFunctions ( ) As String getSystemFunctions ( ) As String getTimeDateFunctions ( ) As String
110
Verso 2
Banco de Dados
supportsExpressionsInOrderBy ( ) As Boolean supportsGroupBy ( ) As Boolean supportsOuterJoins ( ) As Boolean supportsStoredProcedures ( ) As Boolean Vejamos um exemplo, que estabelece uma conexo com uma fonte de dados, obtm e exibe meta dados. Digite o cdigo fonte abaixo e execute a macro.
Sub obtemMetaData ' Dim oContexto As Variant Dim oFonte As Object ' cria o contexto de bases de dados oContexto = createUnoService( "com.sun.star.sdb.DatabaseContext") ' obtem a fonte de dados (usa acesso nomeado) oFonte = oContexto.getByName("Minha_Fonte") ' faz a conexo com a fonte de dados Dim oConexao As Object ' If oFonte.IsPasswordRequired () Then Dim oManip As Variant oManip = createUnoService("com.sun.star.sdb.InteractionHandler") oConexao = oFonte.ConnectWithCompletion(oManip) Else oConexao = oFonte.getConnection("","") End If ' obtem meta dados Dim oMetaData As Object oMetaData = oConexao.getMetaData() ' exibe meta dados MsgBox oMetaData.getURL() + Chr$(10) + _ oMetaData.isReadOnly() + Chr$(10) + _ oMetaData.supportsANSI92EntryLevelSQL() + Chr$(10) + _ oMetaData.supportsSelectForUpdate() + Chr$(10) + _ oMetaData.getMaxColumnNameLength() ' End Sub
Note que, se uma senha for requerida, usamos o mtodo connectWithCompletion (), seno chamamos getConnection (). Aps estabelecer a conexo, chamamos getMetaData () para obter os meta dados. No final, chamamos alguns mtodos de XDatabaseMetaData para exibir informaes do banco de dados. O servio Connection inclui, tambm, o servio com.sun.star.sdbcx.DatabaseDefinition, com outras interfaces. Por enquanto, nos interessa com.sun.star.sdbcx.XTablesSupplier e seu mtodo: getTables ( ) As < com.sun.star.container.XNameAccess > retorna um container com as tabelas ativas na fonte de dados.
Introduo ao OpenOffice.org Basic 111
Banco de Dados
Verso 2
Nas prximas sees, apresentaremos outros mtodos suportados pelo objeto Connection.
Tabelas
As tabelas so os principais componentes da estrutura de um banco de dados e tm uma srie de propriedades e elementos associados. Entre eles podemos citar: colunas, chaves primrias e ndices. O ponto de entrada para operaes como alterao e recuperao de informaes de tabelas so os servios com.sun.star.sdbcx.Table e com.sun.star.sdb.Table. Eles possuem algumas interfaces e propriedades. Entre as suas propriedades, todas somente leitura, temos: Propriedade Privileges Name CatalogName SchemaName Description Type Descrio Valor longo contendo os privilgios da tabela Cadeia com o nome da tabela Cadeia com o nome do catlogo Cadeia com o nome do esquema Cadeia com descrio adicional Cadeia com o tipo da tabela
O grupo de constantes com.sun.star.sdbcx.Privilege, define alguns privilgios de operao sobre uma tabela: SELECT, INSERT, UPDATE, CREATE, ALTER, DELETE, DROP, READ, REFERENCE. O servio com.sun.star.sdb.DataSettings contm propriedades relacionadas com a exibio dos dados da tabela, como filtro e ordenao. Eis algumas:
112 Introduo ao OpenOffice.org Basic
Verso 2
Banco de Dados
Descrio Cadeia com um filtro de dados adicional Se True, aplica o filtro Cadeia descrevendo um tipo de ordenao
As tabelas de uma fonte de dados so obtidas atravs do objeto Connection e do mtodo getTables, j apresentado, como abaixo:
oConexao = oFonte.getConnection(,) oTabelas = oConexao.getTables ( )
O servio com.sun.star.sdbcx.Column traz propriedades (somente leitura), que descrevem as caractersticas de uma coluna. Entre as quais: Propriedade Name Type Precision Scale IsAutoIncrement IsCurrency Description O nome da coluna O tipo de dado ( com.sun.star.sdbc.DataType ) da coluna Descrio
O nmero de dgitos da coluna ( largura ) Nmero de dgitos direita do ponto decimal Se True, a automaticamente Descrio da coluna coluna incrementada
Obtemos as colunas de uma tabela pela interface com.sun.star.sdbcx.XColumnsSupplier: getColumns() As < com.sun.star.container.XNameAccess > retorna um recipiente com as colunas da tabela. A interface com.sun.star.sdbcx.XKeysSupplier e seu mtodo: getKeys () As < com.sun.star.container.XIndexAccess > retorna um recipiente com as chaves da tabela. A interface com.sun.star.sdbcx.XIndexesSupplier fornece os ndices de uma tabela: getIndexes () As < com.sun.star.container.XNameAccess > retorna um recipiente com os ndices da tabela. A interface com.sun.star.sdbcx.XRename usada para renomear uma tabela:
113
Banco de Dados
Verso 2
rename ( sNovoNome As String ) renomeia o objeto A interface com.sun.star.sdbcx.XAlterTable tem os mtodos: alterColumnByName ( sNome As String, oDesc As < com.sun.star.beans.XPropertySet > ) alterColumnByIndex ( iInd As Long, oDesc As < com.sun.star.beans.XPropertySet > ) ambos alteram uma coluna, o primeiro pelo Nome e o segundo pelo ndice, o parmetro oDesc contm o descritor da coluna com as novas propriedades. Vejamos um exemplo, que apresenta informaes sobre as tabelas da fonte de dados Bibliography, distribuda com o OpenOffice.org.
Sub exibeInfoTabelas ' Dim oContexto As Variant Dim oFonte As Object ' cria o contexto de bases de dados oContexto = createUnoService( "com.sun.star.sdb.DatabaseContext") ' obtem a fonte de dados oFonte = oContexto.getByName("Bibliography") ' faz a conexo com a fonte de dados Dim oConex As Object oConex = oFonte.getConnection("","") ' obtem info sobre tabelas e colunas Dim oTabelas As Object Dim oTab As Object Dim oColunas As Object Dim oCol As Object ' obtem a coleo de tabelas (ativas) da fonte de dados oTabelas = oConex.getTables() ' For i = 0 To oTabelas.Count-1 ' obtem a tabela pelo seu ndice oTab = oTabelas.getByIndex(i) sMsg = "TABELA: " + oTab.getName() + Chr$(10) + "COLUNAS:" ' obtem a coleo de colunas da tabela oColunas = oTab.getColumns() sNomeColunas = oColunas.getElementNames() ' For j = 0 To UBound(sNomeColunas) oCol = oColunas.getByName(sNomeColunas(j)) sTipo = oCol.getPropertyValue("TypeName") sMsg = sMsg + Chr$(10) + sNomeColunas(j) + " - " + sTipo Next j MsgBox sMsg ' Next i ' End Sub
Aps a conexo, pegamos a coleo de tabelas com getTables. A seguir, para cada tabela, obtemos as suas colunas com getColumns e os nomes com getElementNames. Depois, visita114 Introduo ao OpenOffice.org Basic
Verso 2
Banco de Dados
mos cada coluna obtendo a propriedade TypeName. No final, exibimos as informaes da tabela. Para a criao de uma tabela, dispomos do servio com.sun.star.sdbcx.TableDescriptor, que contm as propriedades abaixo: Propriedade Name CatalogName SchemaName Description Nome do objeto Descriptor) Descrio a ser criado (do servio
Cadeia com o nome do catlogo Cadeia com o nome do esquema Cadeia com descrio adicional
O servio com.sun.star.sdbcx.ColumnDescriptor tem vrias propriedades, seguem algumas: Propriedade Name Type Precision Scale IsAutoIncrement IsNullable Description O nome da coluna O tipo de dado ( com.sun.star.sdbc.DataType ) da coluna Descrio
O nmero de dgitos da coluna ( largura ) Nmero de dgitos direita do ponto decimal Se True, a automaticamente coluna ncrementada coluna
A interface com.sun.star.sdbcx.XDataDescriptorFactory, cria um descritor de dados para um dado objeto, atravs do mtodo: createDataDescriptor() As < com.sun.star.beans.XPropertySet > retorna um descritor de dados para o objeto associado. Por exemplo: se chamado por um container de tabelas, cria um descritor de tabela; se chamado por um objeto contendo as colunas de uma tabela, cria um descritor de coluna. A interface com.sun.star.sdbcx.XAppend, usada para criar e adicionar um novo objeto num recipiente, contm o mtodo: appendByDescriptor ( oDesc As < com.sun.star.beans.XPropertySet >) cria um novo objeto, usando o descritor oDesc, e adiciona este objeto a um recipiente.
115
Banco de Dados
Verso 2
Demonstrando o uso destas informaes, vamos criar uma macro para adicionar duas tabelas na fonte de dados Minha_Fonte, criada anteriormente.
Sub criaTabelasMinhaFonte ' Dim oContexto As Variant Dim oFonte As Variant oContexto = createUnoService("com.sun.star.sdb.DatabaseContext") ' obtem a fonte de dados If oContexto.hasByName("Minha_Fonte") Then oFonte = oContexto.getByName("Minha_Fonte") Else MsgBox "No existe, saindo ..." Exit Sub End If ' faz a conexo com a fonte de dados Dim oConex As Object oConex = oFonte.getConnection("","") ' obtem tabelas da fonte de dados oTabelas = oConex.getTables() ' cria um descritor de dados para a tabela amigos.dbf oTab = oTabelas.createDataDescriptor() ' define propriedade nome oTab.Name = "amigos" ' obtem colunas da tabela oColunas = oTab.getColumns() ' cria um descritor de dados para uma coluna oCol = oColunas.createDataDescriptor() ' define as propriedades da 1a. coluna oCol.Name = "CODIGO" oCol.Type = com.sun.star.sdbc.DataType.DECIMAL oCol.Precision = 5 ' adiciona a coluna ao container de colunas oColunas.appendByDescriptor(oCol) ' define propriedades da 2a. coluna (oCol preserva os valores) oCol.Name = "NOME" oCol.Type = com.sun.star.sdbc.DataType.VARCHAR oCol.Precision = 50 oColunas.appendByDescriptor(oCol) ' define propriedades da 3a. coluna oCol.Name = "ANIV" oCol.Type = com.sun.star.sdbc.DataType.DATE oColunas.appendByDescriptor(oCol) ' ' adiciona a tabela Amigos ao container de tabelas oTabelas.appendByDescriptor(oTab) ' ' cria um descritor de dados para a tabela fones.dbf oTab = oTabelas.createDataDescriptor() ' define propriedade nome oTab.Name = "fones" ' obtem colunas da tabela oColunas = oTab.getColumns() ' cria um descritor de dados para uma coluna oCol = oColunas.createDataDescriptor() oCol.Name = "CODIGO"
116
Verso 2
Banco de Dados
oCol.Type = com.sun.star.sdbc.DataType.DECIMAL oCol.Precision = 5 oCol.Description = "Cdigo do amigo" oColunas.appendByDescriptor(oCol) oCol.Name = "FONE" oCol.Type = com.sun.star.sdbc.DataType.VARCHAR oCol.Precision = 15 oCol.Description = "Fone do amigo" oColunas.appendByDescriptor(oCol) ' ' adiciona a tabela ao container de tabelas oTabelas.appendByDescriptor(oTab) ' ' encerra a conexo oConex.dispose() ' End Sub
Aps a conexo, chamamos o mtodo getTables, que retorna um container oTabelas, com as tabelas ativas na fonte de dados. Depois, criamos o descritor oTab, da nova tabela e chamamos o mtodo getColumns, criando o container vazio oColunas, para as colunas da nova tabela. A seguir, o descritor oCol criado, suas propriedades definidas e, depois, adicionado a oColunas. Isto repetido para cada nova coluna, aproveitando o mesmo descritor. Em seguida, acrescentamos o descritor da nova tabela ao container oTabelas. Por fim, repetimos o processo para uma segunda tabela e, para evitar problemas, encerramos a conexo.
Chave Primria
Uma chave primria quase obrigatoria em bancos de dados relacionais, principalmente no suporte de algumas operaes como integridade referencial. Atravs do servio com.sun.star.sdbcx.Key, que oferece as interfaces XColumnsSupplier e XDataDescriptorFactory, podemos extrair as informaes de uma chave primria. Ele possui as propriedades abaixo, todas somente leitura: Propriedade Name Type ReferencedTable UpdateRule DeleteRule Nome da chave Tipo da chave (PRIMARY, UNIQUE, FOREIGN) Nome da tabela, somente para chaves externas Regra de externas atualizao, somente para chaves Descrio
117
Banco de Dados
Verso 2
Os tipos possveis para uma chave esto definidos em com.sun.star.sdbcx.KeyType. As regras so definidas em com.sun.star.sdbc.KeyRule, por ex: CASCADE, RESTRICT, etc. O servio com.sun.star.sdbcx.KeyColumn, inclui o servio Column e tem a propriedade: RelatedColumn - nome da coluna relacionada numa tabela externa
Para a criao de chaves primrias, temos o servio com.sun.star.sdbcx.KeyDescriptor, que inclui o servio Descriptor, oferece a interface XColumnsSupplier e tem as mesmas propriedades do servio Key, acima, sem a restrio de somente leitura. O servio com.sun.star.sdbcx.KeyColumnDescriptor, inclui o servio Descriptor, e tem as propriedades: Propriedade Name RelatedColumn Descrio Nome da coluna ( de Descriptor ) Nome da coluna relacionada numa tabela externa
O trecho de cdigo abaixo (no testado), cria uma chave primria para uma tabela:
' ' Cdigo para criar uma Chave Primria
'
' obtem o recipiente com as chaves oChaves = oTabela.getKeys () ' cria um descritor para a chave primria: oChave = oChaves.createDataDescriptor() ' define propriedades da chave oChave.setPropertyValue("Type", com.sun.star.sdbcx.KeyType.PRIMARY) ' obtem as colunas da nova chave oColunasChaves = oChave.getColumns() ' crai um descritor ( s preciso um ) oColChave = oColunasChaves.createDataDescriptor() ' define a propriedade oColChave.setPropertyValue("Name", "ID") ' adiciona a coluna chave oColunasChaves.appendByDescriptor(oColChave) ' adiciona a chave oChaves.appendByDescriptor(oChave) ' adiciona a tabela ao container de tabelas oTabelas.appendByDescriptor(oTabela)
Normalmente, esta operao executada durante a criao da nova tabela, motivo da ltima linha de cdigo.
118
Verso 2
Banco de Dados
ndices
Atravs do servio com.sun.star.sdbcx.Index, podemos obter informaes sobre um ndice de tabela. Ele fornece as interfaces XDataDescriptorFactory e XColumnsSupplier e possui as propriedades a seguir: Propriedade Name Catalog IsUnique IsPrimaryKey IsClustered Nome do ndice Nome do catlogo do ndice Se True, no aceita valores repetidos na coluna Se True, o ndice usado como chave primria Se True, indica que o ndice clustered Descrio
O servio com.sun.star.sdbcx.IndexColumn, que tambm inclui o servio Column, representa as colunas de um ndice e tem a propriedade: IsAscending - Se True, a ordem ascendente
A criao de novos ndices se d pelo servio com.sun.star.sdbcx.IndexDescriptor, que inclui o servio Descriptor, suporta a interface XColumnsSupplier e tem as propriedades: Propriedade Name Catalog IsUnique IsClustered Descrio Nome do ndice ( de Descriptor ) Nome do catlogo do ndice Se True, no aceita valores repetidos na coluna Se True, indica que o ndice clustered
O servio com.sun.star.sdbcx.IndexColumnDescriptor, que inclui o servio Descriptor, permite a criao de colunas para o ndice. Ele tem as propriedades: Propriedade Name IsAscending Descrio Nome da coluna ( de Descriptor ) Se True, a ordem ascendente
Vejamos um exemplo que adiciona um ndice para a tabela amigos.dbf, criada anteriormente.
Sub criaIndiceAmigos ' Dim oContexto As Variant
119
Banco de Dados
Verso 2
Dim oFonte As Variant oContexto = createUnoService("com.sun.star.sdb.DatabaseContext") ' obtem a fonte de dados If oContexto.hasByName("Minha_Fonte") Then oFonte = oContexto.getByName("Minha_Fonte") Else MsgBox "Fonte no existe, saindo ..." Exit Sub End If ' faz a conexo com a fonte de dados Dim oConex As Object oConex = oFonte.getConnection("","") ' obtem tabelas da fonte de dados oTabelas = oConex.getTables() If oTabelas.hasByName("amigos") Then ' obtm a tabela amigos.dbf oTabela = oTabelas.getByName("amigos") Else MsgBox "Tabela no existe, saindo ..." Exit Sub End If ' ' obtm os indices da tabela oIndices = oTabela.getIndexes() ' cria um descritor para um novo indice oIndice = oIndices.createDataDescriptor() ' define propriedades do novo indice oIndice.setPropertyValue("Name", "ami_cod") oIndice.setPropertyValue("IsUnique", True) ' obtem as colunas do indice 'oColunas = oIndice.getColumns() oColunas = oIndice.Columns ' cria um descritor de coluna para o indice oColuna = oColunas.createDataDescriptor() ' define as propriedades da coluna oColuna.setPropertyValue("Name", "CODIGO") oColuna.setPropertyValue("IsAscending", True) ' adiciona a nova coluna ao container de colunas oColunas.appendByDescriptor(oColuna) ' adiciona o indice aos indices da tabela oIndices.appendByDescriptor(oIndice) ' ' fecha a conexo oConex.dispose() ' End Sub
A lgica para a criao de ndices a mesma j apresentada para a chave primria, com uma diferena: um ndice no pode ser adicionado a um descritor de tabela. Antes de prosseguir, procure, nos exemplos que acompanham esta Introduo, a Sub criaIndiceFone e comande a sua execuo, para criar um arquivo ndice para a tabela fones.dbf. Note que este ndice tem a propriedade IsUnique definida como False.
120 Introduo ao OpenOffice.org Basic
Verso 2
Banco de Dados
Segurana
Existem outros elementos, associados estrutura do banco de dados. Vamos apresentar, brevemente, os relacionados com a sua segurana. O servio com.sun.star.sdbcx.Group, representa uma conta para um grupo de usurios. Ele tem a propriedade Nome ( nome do grupo ) e oferece as seguintes interfaces: Interface com.sun.star.sdbcx.XUsersSupplier com o mtodo: getUsers ( ) - retorna os usurios do objeto
Interface com.sun.star.sdbcx.XAuthorizable que define os mtodos: getPrivileges ( ) - obtm os privilgios de acesso ao objeto getGrantablePrivileges ( ) - obtm os privilgios, que podem ser concedidos a outros grantPrivileges ( ) - concede os privilgios revokePrivileges ( ) - revoga os privilgios O servio com.sun.star.sdbcx.User representa um usurio do objeto. Possui a propriedade Name ( nome do usurio ) e oferece as interfaces abaixo. A interface com.sun.star.sdbcx.XUser define o mtodo: changePassword ( sSenhaAtual As String, sNovaSenha As String ) altera a senha do usurio A interface com.sun.star.sdbcx.XGroupsSupplier com o mtodo: getGroups ( ) retorna a coleo de grupos do objeto Para a criao de Grupos e Usurios, temos os servios GroupDescriptor e UserDescriptor. O raciocnio geral o mesmo j visto nesta seo para outros descritores. Finalmente, vamos lembrar que a interface com.sun.star.sdbc.XDatabaseMetaData, fornece uma vasta quantidade de informaes sobre o banco de dados. Ela define diversos mtodos, alguns j apresentados na seo Conexo.
8.5 Registros
A manipulao dos dados contidos numa tabela pode ser efetuada por duas abordagens diferentes. A primeira, utiliza o servio RowSet e usada para fontes registradas no contexto de
121
Banco de Dados
Verso 2
dados do OpenOffice.org. A segunda, atravs de uma comunicao direta com o banco de dados, usando um objeto Statement. Nesta seo veremos apenas a primeira delas.
Criando um RowSet
O servio RowSet utiliza uma conexo para operar sobre tabelas, consultas e comandos SQL. Antes de us-lo, precisamos definir as suas propriedades e ento, executar o seu comando. O servio com.sun.star.sdb.RowSet inclui os servios < sdbc.RowSet > e < sdb.ResultSet >, oferece algumas interfaces e tm uma grande quantidade de propriedades. Eis algumas propriedades de RowSet: Propriedade ActiveConnection DataSourceName Command CommandType Filter Order RowCount IsRowCountFinal IsNew IsModified Descrio Um objeto Conexo gerada por uma fonte ou URL Cadeia com o nome da fonte de dados o comando a ser executado, depende de CommandType O tipo de comando, sdb.CommandType > definido em <
O nome de um filtro para o resultado do comando O nome de uma ordenao para o resultado do comando Nmero de registros acessados na base de dados Se True, indica que todos os registros foram contados Se True, indica que o registro ser inserido no banco de dados Se True, indica que o registro corrente foi alterado
As quatro ltimas propriedades so apenas para leitura. O grupo < com.sun.star.sdb.CommandType > define as seguintes constantes: TABLE QUERY COMMAND - indica que Command receber o nome de uma tabela - indica que Command receber o nome de uma consulta - indica que Command receber um comando SQL
A interface < XResultSetAccess > define o mtodo: createResultSet ( ) As < com.sun.star.sdbc.XResultSet > retorna um objeto < ResultSet >
122
Verso 2
Banco de Dados
O servio com.sun.star.sdbc.RowSet, includo em < sdb.RowSet >, oferece outras interfaces e define outras propriedades. Entre elas: Propriedade MaxRows User Password ResultSetType Descrio Tenta obter o nmero mximo de linhas Nome do usurio para a conexo Senha do usurio para a conexo O tipo do resultado, com.sun.star.sdbc.ResultSetType > de <
A interface < sdbc.XRowSet > define, entre outros, o mtodo: execute ( ) preenche o objeto RowSet com os dados A interface < sdbc.XColumnLocate > permite a localizao de colunas com o mtodo: findColumn ( sNomeCol As String ) As Long a partir do nome da coluna, retorna o seu ndice no objeto RowSet. A interface < sdbc.XParameters > usada para definir parmetros em consultas preparadas. Os seus mtodos tm a forma setXXX onde XXX o tipo de dado da coluna. Vamos a um exemplo de criao de um RowSet, utilizando a tabela biblio, da fonte de dados Bibliography, distribuda com o OpenOffice.org.
Sub criaRowSet ' Dim oRowSet As Variant ' cria RowSet oRowSet = createUnoService("com.sun.star.sdb.RowSet") ' define propriedades para conexo com a fonte de dados oRowSet.setPropertyValue("DataSourceName","Bibliography") oRowSet.CommandType = com.sun.star.sdb.CommandType.TABLE ' para TABLE, passamos o nome da tabela oRowSet.setPropertyValue("Command","biblio") ' executa oRowSet.execute() ' verifica se cursor j est no final do resultado MsgBox "O contador est no fim: " + _ oRowSet.getPropertyValue("IsRowCountFinal") ' posiciona no final oRowSet.last() ' verifica de novo MsgBox "O contador est no fim: " + _
123
Banco de Dados
Verso 2
oRowSet.getPropertyValue("IsRowCountFinal") ' exibe total de registros no resultado MsgBox "H " + Str$(oRowSet.getPropertyValue("RowCount")) + _ " registros!" ' destroi o resultado oRowSet.dispose() ' End Sub
Note que, para usar o RowSet precisamos: criar um objeto, definir as suas propriedades e, ento, chamar o mtodo execute ( ). Aps a criao do objeto RowSet, podemos operar sobre os seus registros, usando as funcionalidades do servio ResultSet.
Verso 2
Banco de Dados
rowInserted ( ) As Boolean rowDeleted ( ) As Boolean verifica o estado do registro ( linha ) corrente. getStatement ( ) As < com.sun.star.uno.XInterface > retorna o comando que deu origem ao ResultSet.
Acessando os dados
A interface XRow define diversos mtodos para acesso aos dados, entre eles: getString ( nColuna As Long ) As String getBoolean ( nColuna As Long ) As Boolean getInt ( nColuna As Long ) As Integer getFloat ( nColuna As Long ) As Single getDouble ( nColuna As Long ) As Double getDate ( nColuna As Long ) As < com.sun.star.util.Date > getTime ( nColuna As Long ) As < com.sun.star.util.Time > getTimestamp ( nColuna As Long ) As < com.sun.star.util.DateTime > retorna o contedo da coluna nColuna wasNull ( ) As Boolean se True, indica que a ltima coluna lida com getXXX ( ) contm um NULL Agora, um exemplo de navegao e acesso aos dados de um RowSet, criado atravs de um comando SQL:
Sub obtendoDadosRowSet ' Dim oRowSet As Variant ' cria RowSet oRowSet = createUnoService("com.sun.star.sdb.RowSet") ' define propriedades para conexo com a fonte de dados oRowSet.setPropertyValue("DataSourceName","Bibliography") oRowSet.CommandType = com.sun.star.sdb.CommandType.COMMAND ' se COMMAND passamos um comando SQL sCmdSQL = "SELECT IDENTIFIER, AUTHOR, TITLE FROM biblio" oRowSet.setPropertyValue("Command", sCmdSQL) ' executa oRowSet.execute() ' obtem indices das colunas nIdent = oRowSet.findColumn("IDENTIFIER") nTitle = oRowSet.findColumn("TITLE") sMsg = "LINHA : IDENT : TTULO(S)" + Chr$(10) ' posiciona curso aps ltimo registro oRowSet.afterLast() ' percorre os registros, do ltimo para o primeiro Do While (oRowSet.previous()) ' obtem nmero da linha
125
Banco de Dados
Verso 2
sLinha = Str$(oRowSet.getRow()) + " " ' obtm o contedo das colunas IDENTIFIER e TITLE sIdent = oRowSet.getString(nIdent) sTitle = oRowSet.getString(nTitle) sMsg = sMsg + sLinha + sIdent + " : " + sTitle + Chr$(10) Loop ' exibe os dados MsgBox sMsg ' destroi o RowSet oRowSet.dispose() ' End Sub
Observe que o comando SQL recupera trs colunas da tabela biblio, mas exibimos apenas duas.
Alterando os dados
A interface XResultSetUpdate, define mtodos para a atualizao dos registros: insertRow ( ) insere o registro no ResultSet e no banco de dados, deve estar no modo de insero. updateRow ( ) atualiza os dados do registro. deleteRow ( ) deleta o registro corrente. cancelRowUpdates ( ) cancela a atualizao do registro, se a operao for suportada. moveToInsertRow ( ) ativa o modo de insero, guardando a posio do registro atual. moveToCurrentRow ( ) retorna para o registro atual quando no modo de insero. A interface XRowUpdate define mtodos para atualizar os dados da linha. Eis alguns: updateString ( nColuna As Long, sCad As String ) updateBoolean ( nColuna As Long, bValor As Boolean ) updateInt ( nColuna As Long, iValor As Integer ) updateFloat ( nColuna As Long, fValor As Single ) updateDouble ( nColuna As Long, dValor As Double ) updateDate ( nColuna As Long, oData As < com.sun.star.util.Date > ) updateTime ( nColuna As Long, oHora As < com.sun.star.util.Time > ) updateTimestamp ( nColuna As Long, oDataHora As < com.sun.star.util.DateTime > ) updateNull ( nColuna As Long )
126 Introduo ao OpenOffice.org Basic
Verso 2
Banco de Dados
atualiza o contedo da coluna nColuna, conforme o tipo de dado. Vejamos um exemplo, que insere cinco registros na tabela amigos.dbf, da fonte de dados Minha_Fonte, criada anteriormente.
Sub insereLinhasRowSet ' Dim oRowSet As Variant ' cria RowSet oRowSet = createUnoService("com.sun.star.sdb.RowSet") ' define propriedades para conexo com a fonte de dados oRowSet.setPropertyValue("DataSourceName","Minha_Fonte") oRowSet.CommandType = com.sun.star.sdb.CommandType.TABLE oRowSet.setPropertyValue("Command","amigos") ' executa oRowSet.execute() ' define novos dados Dim relAmig() ' relao de nomes de amigos Dim relAniv() ' relao de datas de aniversrio Dim dsData As New com.sun.star.util.Date relAmig = Array( "Ana", "Maria", "Jos", "Maria", "MrioXXX") relAniv = Array("10/05/80","01/02/86","05/06/81","05/06/81","20/03/78") ' inicia a insero das linhas For I = 0 To 4 ' ativa modo de insero oRowSet.moveToInsertRow() For J = 1 To 3 If (J = 1) Then ' preenche buffer para coluna tipo DECIMAL oRowSet.updateInt( J, I+1 ) ElseIf (J = 2) Then ' preenche buffer para colunas tipo VARCHAR oRowSet.updateString( J, relAmig(I) ) Else ' converte de string para data dAniv = DateValue( relAniv(I)) ' preenche campos da estrutura ( com.sun.star.util.Date ) dsData.Day = Day( dAniv ) dsData.Month = Month( dAniv ) dsData.Year = Year( dAniv ) ' preenche buffer para colunas tipo DATE oRowSet.updateDate( J, dsData ) End If Next J ' escreve buffer na tabela, saindo do modo de insero oRowSet.insertRow() Next I MsgBox "Registros inseridos: " + Str$(oRowSet.getRow()) ' ' destroi o resultado oRowSet.dispose() ' End Sub
127
Banco de Dados
Verso 2
A destacar: o emprego do mtodo updateXXX ( ) adequado ao tipo de dado da coluna, a definio dos valores dos campos da estrutura < Date > e o fato de insertRow ( ) encerrar o modo de insero ativado pelo mtodo moveToInsertRow ( ). Intencionalmente, inserimos dois registros errados na tabela amigos.dbf. Um, com um erro no nome (MrioXXX), e outro, duplicado (Maria). Vamos corrigir estes erros.
Sub editaRowSet ' Dim oRowSet As Variant ' cria RowSet oRowSet = createUnoService("com.sun.star.sdb.RowSet") ' define propriedades para conexo com a fonte de dados oRowSet.setPropertyValue("DataSourceName","Minha_Fonte") oRowSet.CommandType = com.sun.star.sdb.CommandType.TABLE oRowSet.setPropertyValue("Command","amigos") ' executa oRowSet.execute() ' posiciona na linha duplicada If oRowSet.absolute(4) Then oRowSet.deleteRow() Else MsgBox "Erro: Saindo..." Exit Sub End If ' posiciona antes da primeira linha oRowSet.beforeFirst() Do While (oRowSet.next()) sNome = oRowSet.getString(2) ' coluna NOME a segunda If sNome = "MrioXXX" Then oRowSet.updateString(2, "Mrio") oRowSet.updateRow() Exit Do End If Loop MsgBox rowUpdated() ' ' destroi o resultado oRowSet.dispose() ' End Sub
Inicialmente, apagamos o registro duplicado e em seguida, localizamos e corrigimos o nome na coluna, o mtodo updateRow grava as alteraes de updateString.
128
Verso 2
Banco de Dados
getColumnCount ( ) As Long retorna o nmero de colunas do ResultSet. getColumnName ( nColuna As Long ) As String retorna o nome da coluna nColuna. getPrecision ( nColuna As Long ) As Long retorna a preciso da coluna nColuna. getScale ( nColuna As Long ) As Long retorna a quantidade de dgitos aps o separador decimal. getTableName ( nColuna As Long ) As String retorna o nome da tabela da coluna nColuna, til em resultados com mais de uma tabela. getColumnType ( nColuna As Long ) As Long retorna o tipo SQL da coluna nColuna.
8.6 Consultas
Aps a criao de uma fonte de dados, podemos definir e armazenar consultas utilizadas com frequncia para a recuperao de dados. O principal servio envolvido nesta tarefa com.sun.star.sdb.Query, que inclui outros servios e oferece algumas interfaces. O servio com.sun.star.sdb.QueryDefinition, contm algumas propriedades, como: Propriedade Name Command EscapeProcessing O comando da comando SELECT Descrio O nome da definio (somente leitura) consulta, normalmente um
O servio com.sun.star.sdb.DataSettings, contm propriedades relacionadas com a exibio dos dados e j foi apresentado na seo Tabelas. A interface com.sun.star.sdbcx.XDataDescriptorFactory, define o mtodo: createDataDescriptor ( ) As < com.sun.star.beans.PropertySet > crai um descritor de dados para o objeto. A interface com.sun.star.sdbcx.XRename usada para renomear objetos, atravs do mtodo: rename ( sNovoNome As String ) renomeia o objeto.
Introduo ao OpenOffice.org Basic 129
Banco de Dados
Verso 2
A interface com.sun.star.sdbcx.XColumnsSupplier obtm as colunas do objeto com o mtodo: getColumns ( ) As < com.sun.star.container.XNameAccess > retorna as colunas contidas no objeto. A definio de consultas, se d atravs da interface XQueryDefinitionsSupplier e seu mtodo: getQueryDefinitions ( ) As < com.sun.star.container.XNameAccess > retorna um container com as definies das consultas. O container retornado suporta o mtodo createInstance( ) para a criao de uma nova consulta ou podemos, ainda, usar a funo Basic createUnoService. Vejamos um exemplo que define uma consulta para a fonte de dados Minha_Fonte.
Sub criaConsulta Dim oContexto As Variant Dim oFonte As Object oContexto = createUnoService( "com.sun.star.sdb.DatabaseContext") oFonte = oContexto.getByName("Minha_Fonte") ' obtem o recipiente com as definies de consultas Dim oDefCons As Object oDefCons = oFonte.getQueryDefinitions() ' cria uma instancia para uma consulta Dim oConsulta As Object oConsulta = oDefCons.createInstance() ' OU: ' oConsulta = createUnoService ("com.sun.star.sdb.QueryDefinition") ' define as propriedades oConsulta.Command = "SELECT * FROM amigos" ' insere a consulta no recipiente oDefCons.insertByName("Consulta_1", oConsulta) ' verifica MsgBox oDefCons.hasByName("Consulta_1") ' End Sub
Observe que no necessrio estabelecer uma conexo para definir novas consultas. As propriedades a serem definidas, so as mesmas do servio QueryDefinition, j apresentadas. Consultas podem ser criadas, ainda, atravs do servio QueryDescriptor e suas interfaces. A lgica similar quela j apresentada na criao de ndices para tabelas. O acesso s consultas, aps estabelecer uma conexo, pode ocorrer atravs da interface XQueriesSupplier e seu mtodo: getQueries ( ) As < com.sun.star.container.XNameAccess > retorna um container com as consultas. O exemplo a seguir, cria uma conexo com a fonte de dados e obtm as colunas da consulta armazenada anteriormente.
130
Verso 2
Banco de Dados
Sub exibeColunasConsulta Dim oDbCont As Variant Dim oDbFonte As Object oDbCont = createUnoService( "com.sun.star.sdb.DatabaseContext") oDbFonte = oDbCont.getByName("Minha_Fonte") ' faz a conexo com a fonte de dados Dim oDbCon As Object oDbCon = oDbFonte.getConnection("","") ' obtem o recipiente com as consultas Dim oDefCons As Object oDefCons = oDbCon.getQueries() ' obtem a consulta e suas colunas Dim oConsulta As Object Dim oColunas As Object oConsulta = oDefCons.getByName("Consulta_1") oColunas = oConsulta.getColumns() ' obtem nome da coluna e tipo de dado Dim oCol As Object Dim sNomes() As String sNomes = oColunas.getElementNames() sMsg = "" For i = LBound(sNomes) To UBound(sNomes) oCol = oColunas.getByName(sNomes(i)) sMsg = sMsg + sNomes(i) + " - " + _ oCol.getPropertyValue("TypeName") + Chr$(10) Next i MsgBox sMsg + "Total: " + Str$(i) + " Colunas" End Sub
A execuo de uma consulta ocorre atravs do servio < RowSet >, de modo anlogo ao j apresentado na seo sobre Registros. Vejamos um exemplo.
Sub executaConsulta ' Dim oRowSet As Variant ' cria RowSet oRowSet = createUnoService("com.sun.star.sdb.RowSet") ' define propriedades para conexo com a fonte de dados oRowSet.setPropertyValue("DataSourceName","Minha_Fonte") oRowSet.CommandType = com.sun.star.sdb.CommandType.QUERY ' se QUERY passamos o nome de uma consulta oRowSet.setPropertyValue("Command", "Consulta_1") ' executa oRowSet.execute() ' obtem indices das colunas nIdent = oRowSet.findColumn("CODIGO") nNome = oRowSet.findColumn("NOME") sMsg = "LINHA: CODIGO: NOME(S)" + Chr$(10) ' percorre os registros Do While (oRowSet.next()) ' obtem nmero da linha sLinha = Str$(oRowSet.getRow()) + " " ' obtm o contedo das colunas CODIGO E NOME sIdent = oRowSet.getInt(nIdent)
131
Banco de Dados
Verso 2
sNome = oRowSet.getString(nNome) sMsg = sMsg + sLinha + sIdent + " : " + sNome + Chr$(10) Loop ' exibe os dados MsgBox sMsg ' destroi o RowSet oRowSet.dispose() ' End Sub
O nico aspecto a destacar CommandType definida como QUERY e a passagem do nome da consulta para Command. As funcionalidades de RowSet so as mesmas j apresentadas anteriormente. Como informao, a API do OpenOffice.org oferece, tambm, ferramentas para a composio de consultas, atravs do servio com.sun.star.sdb.SQLQueryComposer e da interface XSQLQueryComposerFactory.
Verso 2
Banco de Dados
SCROLL_INSENSITIVE SCROLL_SENSITIVE
A interface < com.sun.star.sdbc.XStatement > usada para a execuo de comandos SQL e obteno do resultado do comando. Possui os mtodos: executeQuery ( sCmdSQL As String ) As ResultSet executa um comando que retorna um resultado simples ( um ResultSet ) executeUpdate ( sCmdSQL As String ) As Long executa um comando SQL de atualizao, para comandos DDL retorna zero. execute ( sCmdSQL As String ) As Boolean executa um comando SQL que pode retornar mltiplos resultados getConnection ( ) retorna a conexo que originou este comando. A interface < com.sun.star.sdbc.XMultipleResults > usada para verificar mltiplos resultados de um comando SQL. Define os mtodos: getResultSet ( ) As < ResultSet > retorna o resultado corrente getUpdateCount ( ) As Long retorna o contador de resultados getMoreResults ( ) As Boolean move para o prximo comando Vejamos um exemplo de uso do servio Statement, que opera sobre a tabela amigos, da fonte de dados Minha_Fonte, retornando as colunas NOME e ANIV dos registros com CODIGO maior ou igual a 2.
Sub exemploSQLSelect ' Dim oContexto As Variant Dim oFonte As Object ' cria o contexto de bases de dados oContexto = createUnoService( "com.sun.star.sdb.DatabaseContext") ' obtem a fonte de dados oFonte = oContexto.getByName("Minha_Fonte") ' faz a conexo com a fonte de dados Dim oConexao As Object oConexao = oFonte.getConnection("","") ' obtem o resultado de uma consulta Dim oComando As Object Dim oResultado As Object oComando = oConexao.createStatement() ' define o comando SQL
133
Banco de Dados
Verso 2
sCmdSQL = "Select NOME, ANIV From amigos Where CODIGO >= 2" ' executa o comando oResultado = oComando.executeQuery(sCmdSQL) ' percorre o resultado sMsg = "" n = 0 Do While ( oResultado.next()) sMsg = sMsg + oResultado.getString(1) + Chr$(10) n = n + 1 Loop MsgBox sMsg + "Linhas: " + Str$(n) ' End Sub
Note que: estabelecemos uma conexo, criamos o comando e chamamos o mtodo apropriado, neste caso executeQuery, que retorna um ResultSet. Por fim, percorremos o resultado. O servio ResultSet, e suas principais interfaces, j foi apresentado na seo sobre Registros. A lgica a mesma para os comandos SQL de atualizao ( Insert, Update, Delete ) ou comandos que alterem a estrutura do banco de dados ( Create Table, Drop, etc ). O mtodo executeUpdate retorna o nmero de linhas para comandos SQL e zero para comandos DDL. A atualizao possivel, tambm, atravs dos mtodos das interfaces de ResultSet, como j apresentado na seo sobre Registros.
134
Verso 2
Banco de Dados
A interface < com.sun.star.sdbc.XPreparedStatement > tem funcionalidade similar a XStatement e define os mtodos: executeQuery ( ) As ResultSet executeUpdate ( ) As Long execute ( ) As Boolean getConnection ( ) Todos com funcionalidade igual aos da interface < XStatement >, mas sem parmetros. A interface < com.sun.star.sdbc.XParameters >, encarrega-se da definio dos valores dos parmetros, contendo vrios mtodos, entre os quais: setBoolean ( nIndice As Long, bValor As Boolean ) setInt ( nIndice As Long, nValor As Long ) setFloat ( nIndice As Long, fValor As Single ) setDouble ( nIndice As Long, dValor As Double ) setString ( nIndice As Long, sValor As String ) setDate ( nIndice As Long, stValor As < com.sun.star.util.Date > ) setTime ( nIndice As Long, stValor As < com.sun.star.util.Time > ) setTimestamp ( nIndice As Long, stValor As < com.sun.star.util.DateTime > ) Define o valor do parmetro nIndice. Eles so numerados na ordem em que aparecem no comando SQL. clearParameters ( ) limpa os valores dos parmetros imediatamente J dispomos dos elementos para apresentar um exemplo ilustrativo:
Sub parametroSQLSelect ' Dim oContexto As Variant Dim oFonte As Object ' cria o contexto de bases de dados oContexto = createUnoService( "com.sun.star.sdb.DatabaseContext") ' obtem a fonte de dados oFonte = oContexto.getByName("Minha_Fonte") ' faz a conexo com a fonte de dados Dim oConexao As Object oConexao = oFonte.getConnection("","") ' define o comando SQL parametrizado sCmdSQL = "Select * From amigos Where CODIGO >= ?" ' prepara o comando Dim oComando As Object oComando = oConexao.prepareStatement(sCmdSQL) ' define o valor do parmetro nValor = 2 oComando.setInt(1, nValor) ' o campo DECIMAL ' obtem o resultado da consulta Dim oResultado As Object oResultado = oComando.executeQuery()
135
Banco de Dados
Verso 2
' percorre o resultado sMsg = "" n = 0 Do While ( oResultado.next()) sMsg = sMsg + oResultado.getString(2) + Chr$(10) n = n + 1 Loop MsgBox sMsg + "Linhas: " + Str$(n) ' libera os recursos oComando.close() ' End Sub
Observe que o comando SQL passado como argumento do mtodo prepareStatement, depois definimos o valor do parmetro com um dos mtodos setXXX e, s ento, chamamos o mtodo executeQuery. A lgica para atualizaes a mesma, mas devemos chamar o mtodo executeUpdate.
Aps a preparao do comando, ele dever ser executado com um dos mtodos da interface XPreparedStatement. Se a consulta ou o comando SQL tiver parmetros, cada um deles, dever ser definido com o mtodo setXXX, apropriado ao seu tipo de dado. O bloco de cdigo a seguir, demonstra esta abordagem:
' prepara o comando Dim oComando As Object ' Consulta_2 est armazenada na fonte de dados: ' Select * From amigos Where CODIGO >= ? sComando = "Consulta_2"
136
Verso 2
Banco de Dados
nTipo = com.sun.star.sdb.CommandType.QUERY oComando = oConexao.prepareCommand( sComando, nTipo) ' define o valor do parmetro nValor = 2 oComando.setInt(1, nValor) ' o campo DECIMAL ' obtem o resultado da consulta Dim oResultado As Object oResultado = oComando.executeQuery() ' percorre o resultado
Observe que: sComando depende de nTipo, o mtodo prepareCommand retorna um objeto PreparedStatement e a definio do parmetro da consulta segue o padro anterior.
8.10 Vnculos
Alm de tabelas e consultas, uma fonte de dados permite a definio de vnculos com documentos do OpenOffice.org. Este documentos podem conter formulrios ou outros objetos, como campos, dependentes de um banco de dados. O acesso aos vnculos possivel atravs da interface com.sun.star.sdb.XBookmarksSupplier e seu mtodo: getBookmarks ( ) As < com.sun.star.container.XNameAccess > retorna um container com.sun.star.sdb.DefinitionContainer, contendo os vnculos da fonte de dados. Podemos adicionar ou remover elementos do container, usando os mtodos de XNameContainer. insertByName ( sNome As String, sMarcador As Variant ) sNome o nome do vnculo e sMarcador a URL do documento. removeByName ( sNome As String ) sNome o nome do vnculo Os marcadores devem conter o caminho completo do documento na forma file:///caminho. Para manter a consistncia, um exemplo:
Sub vinculosFonteDados Dim oContexto As Variant Dim oFonte As Variant Dim oVinculos As Object ' oContexto = createUnoService("com.sun.star.sdb.DatabaseContext") oFonte = oContexto.getRegisteredObject("Minha_Fonte") ' obtem o container com os vnculos oVinculos = oFonte.getBookmarks() ' adiciona um novo marcador sURL = "file:///D:/NAD/OPENOFFICE/TESTMACROS.SXW" oVinculos.insertByName("Meu_Novo_Vinculo1", sURL)
137
Banco de Dados
Verso 2
' obtm as URLs dos vnculos sMsg = "" For I = oVinculos.getCount() To 1 Step -1 sMsg = sMsg + "URL: " + oVinculos.getByIndex(I-1) + Chr$(10) Next I MsgBox sMsg ' End Sub
Aqui, adicionamos um vnculo na fonte Minha_Fonte e, em seguida extramos as URLs dos vnculos registrados na fonte de dados. De posse da URL de um documento, podemos carreg-lo, conforme o explicado no captulo Trabalhando com Documentos, usando o mtodo: loadComponentFromURL ( lista_de_parametros ) consulte o captulo Trabalhando com Documentos, para mais detalhes.
138
Verso 2
sHora = Hour ( Now ) sNome = InputBox ( "Digite o seu Nome:", "Caixa de entrada", "Operador" ) If ( sHora > 6 And sHora < 18 ) Then sSauda = "Bom Dia! " Else sSauda = "Boa Noite! " End If MsgBox sSauda + sNome
139
Verso 2
Voc acabou de criar uma macro chamada Main. Vamos executar a macro: selecione, na barra de menu, Ferramentas Macro. No dilogo Macro, clique sobre o boto Executar. Surge uma caixa de entrada, solicitando o seu nome, digite-o e clique sobre o boto Ok. Surgir um dilogo com uma saudao, clique em Ok para encerrar a execuo da macro. Se ocorrer algum erro, revise o cdigo digitado e recomece. Vamos analisar, passo a passo, o nosso cdigo fonte: REM ***** BASIC ***** Esta linha contm um comentrio. Comentrios no so executados. Sub Main Esta linha declara e define uma sub-rotina chamada Main e deve estar acompanhada de uma linha End Sub. Entre as duas linhas deve vir o cdigo fonte que d funcionalidade a sub-rotina. Dim sNome As String ' varivel para guardar o nome Dim sSauda As String ' varivel para guardar a saudao Dim sHora As Integer ' varivel para guardar a hora do sistema Estas linhas declaram e inicializam as variveis que sero usadas na macro. O apstrofe marca o incio de comentrios numa linha de cdigo. sHora = Hour ( Now ) Aqui, chamamos duas funes internas do Basic. A funo Now, obtm a hora completa do sistema (hh:mm:ss). A funo Hour recebe o valor retornado por Now e extrai somente a hora. Em seguida, o valor obtido por Hour ( a hora ) armazenado na varivel sHora. Neste contexto, o sinal de igual ( = ) chamado operador de atribuio. Tudo que estiver do lado direito do operador de atribuio recebe o nome de expresso, neste caso Hour ( Now ). sNome = InputBox ( "Digite o seu Nome:", "Caixa de entrada", "Operador" ) Esta linha chama a funo InputBox, do Basic, que apresenta a caixa de dilogo para lidar com a entrada do nome do operador. Note que passamos trs cadeias de caracteres para esta funo. Estes valores (as cadeias) so chamados de parmetros da funo. O primeiro parmetro uma mensagem para o operador, o segundo o ttulo do dilogo e o terceiro o valor padro da caixa de texto. A funo InputBox retorna o contedo da caixa de texto se voc clicar sobre o boto Ok, seno ( clique sobre o boto Cancelar ou Fechar ) retorna uma cadeia vazia. Aps encerrar o dilogo, o valor retornado ser atribudo varivel sNome. Ainda, sobre parmetros, podemos dizer que a funo Now no tm parmetro e que a funo Hour recebe um parmetro. If ( sHora > 6 And sHora < 18 ) Then Aqui, iniciamos a execuo de um comando de deciso. Estamos dizendo ao Basic: se o valor armazenado na varivel sHora for maior que 6 e menor que 18 ento execute o prximo
140 Introduo ao OpenOffice.org Basic
Verso 2
bloco de cdigo. Os sinais > e < so chamados operadores relacionais. A palavra And chamada de operador lgico. O contedo entre parnteses uma expresso composta que ser avaliada como Verdadeira (True) ou Falsa (False). Ela ser verdadeira, se ambas as expresses ( sHora > 6; sHora < 18) forem verdadeiras. sSauda = "Bom Dia! " A expresso Bom Dia! ser atribuda a sSauda, se a expresso da linha anterior for avaliada como verdadeira (True). Else Seno, a expresso foi avaliada como falsa (False), execute o prximo bloco de cdigo. sSauda = "Boa Noite! " A expresso Boa Noite! atribuda varivel sSauda. End If Esta linha indica o final do comando de deciso IF ... THEN ... ELSE ... END IF. MsgBox sSauda + sNome Esta linha chama a sub-rotina MsgBox, do Basic, que exibe uma caixa de mensagem para o operador. Ela recebe um parmetro, neste caso a expresso sSauda + sNome. O sinal ( + ), neste contexto, chamado de operador de concatenao, pois junta as cadeias de caracteres guardadas nas variveis sSauda e sNome. Clique sobre o boto OK para fechar a caixa de mensagem. End Sub Esta linha indica o trmino da sub-rotina, iniciada na linha SUB Main. No esquea, uma linha SUB ... precisa estar associada a uma linha END SUB. Neste tpico, voc aprendeu diversos conceitos (esto em negrito) relacionados com a linguagem Basic. Se algum ponto no foi compreendido, execute novamente o exemplo e leia o passo a passo, tentando associar o que ocorreu durante a execuo com as linhas de cdigo.
Palavras reservadas
Uma palavra reservada um identificador ( nome ) utilizado internamente pela linguagem Basic. As palavras reservadas do Basic so aquelas usadas nos seus comandos, nas suas funes internas, nas suas constantes e nos seus operadores. Abaixo, alguns exemplos: BEEP - comando do Basic
141
Verso 2
CALL - comando do Basic SUB - comando do Basic FOR - parte de um comando do Basic NEXT - parte de um comando do Basic EXIT - parte de comandos do Basic WHILE - parte de comandos do Basic DO - parte de comandos do Basic STR$ - funo do Basic TRIM$ - funo do Basic SQR - funo do Basic AND - operador do Basic OR - operador do Basic PI - constante definida pelo Basic O principal sobre estas palavras : elas no podem ser usadas como nomes para identificar variveis, constantes ou procedimentos definidos pelo programador.
Comentrios
Numa macro, as linhas iniciadas por apstrofe ou pela palavra reservada REM ( de REMarker) so consideradas como comentrios, portanto no so processadas.
' Isto um comentrio REM O cdigo abaixo inicializa as variveis de ambiente
142
Verso 2
Os comentrios (com apstrofe) podem ser colocados na frente de uma linha de cdigo.
DIM coord_X As Double DIM coord_Y As Double ' varivel para guardar a coordenada X do ponto ' varivel para guardar a coordenada Y do ponto
Declarao de variveis
Podemos declarar variveis explicitamente com a palavra reservada DIM, do modo abaixo: DIM nome_da_variavel AS tipo_de_dado Ou: DIM nome_da_variavel seguido do caractere indicador do tipo de dado nome_da_variavel um nome definido pelo programador, conforme as regras de nomeao. Exemplos:
DIM varInteira AS INTEGER DIM varInteira% ' Declara uma variavel inteira ' Declara uma variavel inteira (%)
143
Verso 2
DIM DIM DIM DIM DIM DIM DIM DIM DIM DIM
varIntLongo AS LONG varIntLongo& varString AS STRING varString$ varSingle AS SINGLE varSingle! varDupla AS DOUBLE varDupla# varPreco AS CURRENCY varPreco@
' ' ' ' ' ' ' ' ' '
Declara Declara Declara Declara Declara Declara Declara Declara Declara Declara
uma uma uma uma uma uma uma uma uma uma
variavel variavel variavel variavel variavel variavel variavel variavel variavel variavel
longa longa (&) string string ($) real simples real simples (!) real dupla real dupla(#) moeda moeda (@)
Podemos declarar uma varivel, no momento do seu emprego, acrescentando o caractere de tipo ao nome da varivel, como nos exemplos abaixo:
UmInteiro% = 1500 UmLongo& = 2195678 MeuNome$ = JOS DE ANDRADE UmRealSimples! = 15.555 UmRealDuplo# = coordEne * sin(30) ' ' ' ' ' declara declara declara declara declara um inteiro um inteiro longo uma cadeia um real simples um real duplo
Se o tipo de dado no for indicado a varivel ser assumida como Single. O valor de uma varivel declarada ser 0 para tipos numricos, uma cadeia nula para Strings e False para Boolean. recomendvel a declarao explcita das variveis de um programa, bem como a escolha de nomes significativos para as mesmas. Para forar a declarao de todas as variveis, use a linha de comando abaixo, no incio do mdulo: OPTION EXPLICIT
Matrizes
Matrizes contm um grupo de variveis com caractersticas comuns e com o mesmo tipo de dado. Com uma matriz podemos usar um s nome de varivel e acessar os valores de um elemento usando um ndice. Uma matriz tem um limite inferior e um limite superior em cada dimenso. Os ndices so valores inteiros (negativos ou positivos). At 16.368 elementos podem ser endereados. Matrizes so estruturas de dados prprias para uso dentro de laos. Exemplos de emprego de matrizes:
Dim nomeDePonto (30) AS String 'Vetor para 31 nomes de pontos (0 a 30) Dim coordPonto3D# (30, 2) ' Matriz de 2 dimenses com 31 linhas e ' 3 colunas (X, Y e Z) do tipo Double ' Atribuindo valores nomeDePonto(0) = Ponto01 ' atribui a cadeia ao 1o. elemento do vetor nomeDePonto(30) = Ponto31 ' atribui a cadeia ao ltimo elemento do vetor
144
Verso 2
' Acessando valores coordX = coordPonto3D(9,0) ' obtm o valor da linha 10, coluna 1 coordY = coordPonto3D(9,1) ' obtm o valor da linha 10, coluna 2 coordZ = coordPonto3D(9,2) ' obtm o valor da linha 10, coluna 3
Os ndices inferior e superior podem ser definidos com a clusula TO, por exemplo:
Dim sNomes$(1 To 30) Dim matrizA%(1 To 5, 1 To 3) ' Declara vetor para 30 (1 a 30) nomes ' Declara matriz de 5 linhas X 3 colunas
Podemos declarar uma matriz cujo tamanho ser determinado posteriormente. Dim nomePonto$( ) ' Declara um vetor de tamanho desconhecido Aps conhecer o nmero de pontos, podemos redimensionar o vetor com REDIM: NumeroPontos = 100 Redim nomePonto(numeroPontos) 'redimensiona o vetor para 101 nomes (0 a 100) REDIM apaga o contedo do vetor, se quisermos aumentar o tamanho do vetor preservando seu contedo, devemos usar a clusula PRESERVE, veja abaixo: REDIM PRESERVE nomePonto(200) ' aumenta de 100 para 200 conservando o contedo
Sub trocaValor(valor1%, valor2%) Dim temp% ' temp visvel apenas em trocaValor ' ... outros comandos End Sub Sub Main Dim var1 As Integer ' visvel apenas pela Sub Main pesoLinha% = 2 ' visvel apenas pela Sub Main ' ... outros comandos End Sub
145
Verso 2
A declarao de uma varivel pblica deve ser feita antes de qualquer sub-rotina ou funo na macro. As variveis locais existem apenas enquanto a sub-rotina ou funo, na qual elas foram declaradas, so executadas.
Constantes simblicas
Para facilitar a leitura de uma macro, os valores literais (1000, S, 2.718), usados ao longo da mesma, devem ser declarados como constantes simblicas, com o comando CONST, fora de qualquer sub-rotina ou funo, assim:
' declarao de constantes Const NR_PONTOS% = 1000 Const SIM$ = S Const BASE_NATURAL# = 2.718 ' nmero de pontos = 1000 ' constante SIM = S ' base log. naturais
Posteriormente, podemos usar estas constantes numa expresso, no lugar dos seus valores literais, por exemplo:
DIM coordX (NR_PONTOS) As Double valor# = valor1 * BASE_NATURAL If (Resposta$ = SIM) Then ' se resposta = S ento ' execute os comandos End If ' declara vetor com 1001 elementos ' bem mais compreensvel!
Aps a declarao de uma constante, o seu valor no poder ser mudado dentro do programa. Constantes simblicas facilitam a manuteno do programa, pois voc precisa alterar apenas o seu valor, em vez de todas as ocorrncias do valor literal dentro do programa. O OpenOffice.org Basic possui as seguintes constantes pr-definidas ( PI, True, False ).
Expresses
Uma expresso uma constante, uma varivel, uma funo, ou qualquer combinao destas, separadas por operadores e parnteses, escrita segundo as regras do Basic e passvel de avaliao. Seguem os principais elementos encontrados em expresses. Operador de Atribuio O resultado de uma expresso pode ser atribuido a uma varivel com o uso do operador de atribuio, o sinal de igual ( = ). Note que neste contexto, o sinal de igual no significa uma comparao, mas sim uma atribuio, isto , o resultado da expresso do lado direito do sinal ser atribudo varivel do lado esquerdo do sinal. Exemplos:
146
Verso 2
' declara as variveis diametro e raio Dim diametro#, raio# ' atribui o valor 2.0 ao raio ( 2.0 uma expresso ) raio = 2.0 ' atribui o resultado da expresso ( 2 * raio ) a diametro diametro = 2 * raio
Operadores Aritmticos So usados com operandos numricos e produzem resultados numricos. Os operandos podem ser constantes numricas, variveis numricas ou funes que retornam valores numricos. Os operadores so: Operador + * / \ Mod ^ Exemplos:
' valor = 0.5 ( note que 5 e 10 so promovidos a Double ) valor# = 5/10 ' cos() uma funo interna do Basic cosTeta# = cos (1.555 ) ' PI uma constante do Basic area# = 2 * PI * raio ^ 2 ' r, a, b, c, d, e so variveis numricas r = (a + b) * (c - d / e)
Usado para Somar expresses Subtrair expresses Multiplicar expresses Dividir a primeira pela segunda expresso Dividir expresses inteiras Obter o resto de uma diviso inteira Exponenciao
Operando s 2 2 2 2 2 2 2
Operadores de Concatenao de Cadeias So usados para juntar duas ou mais cadeias de caracteres. Operador & + Usado para Concatenar duas ou mais cadeias ( strings ) Concatenar duas ou mais cadeias ( strings )
Exemplos:
147
Verso 2
Operadores Relacionais ( Comparao ) So usados para comparar expresses e o resultado um Booleano, True (-1) ou False (0). Operador = <> > < >= <= Usado para As expresses so iguais ? As expresses so diferentes ? A primeira expresso maior que a segunda ? A primeira expresso menor que a segunda ? A primeira expresso maior que ou igual a segunda ? A primeira expresso menor que ou igual a segunda ?
Operadores Lgicos Se usados com operandos Booleanos e/ou expresses Booleanas, resultam num valor Booleano. Se usados com operandos numricos, executam uma operao bit a bit, resultando num valor numrico. Operador NOT OR AND XOR EQV IMP Usado para Inverte o resultado booleano Uma das expresses TRUE ? Ambas as expresses so TRUE ? Uma expresso TRUE e a outra FALSE ? Ambas so TRUE ou ambas so FALSE ? Se a 1a. for TRUE a 2a precisa ser TRUE Operando s 1 2 2 2 2 2
148
Verso 2
Exemplos:
' ' resultado True, se as 2 expresses forem True ' FIM_ARQUIVO uma constante definida anteriormente resultado = (NrPtos < 1000 And Not FIM_ARQUIVO) ' ' resultado True se a 1a. ou a 2a. for True ' EOF() uma funo do Basic resultado = (NrPtos < 1000 Or Not EOF())
Precedncia dos Operadores Uma expresso pode ser composta por mais de um operador. A ordem na qual estes operadores so avaliados chama-se precedncia dos operadores, da maior para a menor temos: () Parnteses ^ Exponenciaco *, / Multiplicao e diviso \ Diviso inteira Mod Mdulo +, Soma e subtrao =, <>, >, <, >=, <= Operadores relacionais Not, And, Or, Xor, Eqv, Imp Operadores lgicos nesta ordem Para forar a avaliao de uma expresso podemos, sempre, usar parnteses (maior precedncia). Exemplo:
valor1 = 6 + 6 / 3 valor2 = ( 6 + 6 ) / 3 ' aps avaliao valor1 ' aps avaliao valor2 = = 8 4
Verso 2
' ' Execute este bloco de comandos ' End If Fim Se Segunda forma do comando IF (com a clusula ELSE): If ( expresso ) Then ' Se expresso for True Ento ' Execute este bloco de comandos Else ' Execute este bloco de comandos End If ' Fim Se Terceira forma do comando IF (com a clusula ELSE IF): If (expresso) Then ' Se expresso for True Ento ' Execute este bloco de comandos ElseIf (expresso) Then ' Execute este bloco de comandos Else ' Execute este bloco de comandos End If ' Fim Se Em todas as formas o uso dos parnteses opcional. Podemos aninhar vrios comandos If. Exemplo da segunda forma do comando IF:
If (a > b) Then maior = a Else maior = b End If ' ' ' ' ' se a for > que b, ento armazene o valor de a na variavel maior seno armazene o valor de b na variavel maior fim se
150
Verso 2
Case lista_de_expresses1 ' execute este bloco de comandos Case lista_de_expresses2 ' execute este bloco de comandos Case Else ' execute este bloco de comandos End Select ' fim da seleo A instruo Select Case avalia a expresso_de_teste somente uma vez, na entrada do comando, em seguida, compara seu resultado com a lista_de_expresses das clusulas Case. Se houver uma coincidncia, os comandos abaixo do Case sero executados. Os comandos de Case Else (que opcional) sero executados se no houver nenhuma coincidncia anterior. A lista de expresses pode conter mais de uma expresso ou at uma faixa de valores (Ex: 10 To 20), com cada expresso separada por vrgula. As expresses devem ser do mesmo tipo de dado da expresso_de_teste. Aps a execuo do bloco de comandos, o controle passa para a prxima linha depois do End Select. Exemplo de Select Case avaliando constantes:
Select Case tipoDesenho Case LINHA ' executa comandos para Case CIRCULO ' executa comandos para Case CURVA ' executa comandos para Case Else ' avisa ao operador que End Select
151
Verso 2
' executa este bloco de comandos ' Wend ' fim enquanto Este comando avalia a expresso_de_teste no incio, se o resultado for True, o bloco de comandos ser executado e o controle volta para o While para uma nova avaliao da expresso. Seno o comando aps o Wend ser executado. permitido aninhar laos While ... Wend. Exemplo de While ... Wend:
Sub exemplo_While_Wend ' Dim nomeArq As String Dim sPasta As String Dim nrArq As Integer ' nrArq = 0 ' inicializa contador de arquivos sPasta = CurDir() ' obtm a pasta corrente nomeArq = Dir$( sPasta, 0 ) ' obtem nome do primeiro arquivo ' While (nomeArq <> "") ' enquanto tiver nome arquivo ' ' aqui, podemos executar alguma tarefa sobre o arquivo ' nomeArq = Dir$() ' retorna nome do prximo arquivo ou "" nrArq = nrArq + 1 ' incrementa nr de arquivos Wend ' fim enquanto ' MsgBox Str$(nrArq) + " arquivos, na pasta: " + sPasta ' End Sub
Neste exemplo, obtemos a pasta corrente e todos os nomes de arquivos, com atributo normal, nela existentes. As funes CurDir, Dir e Str$ so internas ( do Basic ). Note que na primeira chamada da funo Dir, passamos dois parmetros e nas prximas chamadas, dentro do lao, no passamos nenhum parmetro.
152
Verso 2
O valor_inicial atribudo varivel Contador, depois ele testa o contador com o valor_final, se o resultado do teste for True, os comandos dentro do lao sero executados, em seguida Contador ser incrementado com valor_incremento e um novo teste ser executado, at que se obtenha um valor False para o teste, conforme as regras: Para valor do incremento positivo, o teste ser True se Contador <= valor_final. Para valor do incremento negativo, o teste ser True se Contador >= valor_final. Se a clusula STEP for omitida o valor_incremento ser 1. O teste com IF deve ser usado se quisermos sair do lao antes que Contador bata com o valor_final. Exemplo de For ... Next:
' Inicializar um vetor de 100 elementos ' Sub exemplo_For_Next Dim Vetor(1 To 100) As Integer Dim I As Integer ' ' para I variando de 1 a 100 com incremento 1 For I = 1 To 100 ' I usado como ndice do vetor e tambm na expresso Vetor(I) = I * 2 Next I ' vai para a prxima avaliao de I ' exibe resultado da soma do 1o e ltimo elementos MsgBox Str$ ( Vetor(1) + Vetor(100) ) ' End Sub
Aqui, definimos um vetor com 100 elementos, com o ndice inicial em 1 e o final em 100 ( se voc no especificar o ndice inicial, o OOo Basic adota o zero ). Depois, entramos no lao e atribumos valores ( I * 2 ) para os elementos do vetor. Terminamos exibindo a soma dos primeiro e ltimo elementos do vetor. O comando For ... Next muito eficiente e deve ser usado sempre que soubermos o nmero de repeties do lao. Podemos aninhar comandos For ... Next ( muito til para operaes com matrizes ).
Verso 2
IF (expresso) THEN EXIT DO ' sai do lao END IF LOOP ' retorna para o Do Segunda, teste no incio do comando com WHILE DO WHILE (expresso) ' faa ENQUANTO expresso for True ' executa bloco de comandos LOOP ' retorna para o Do Terceira, teste no incio do comando com UNTIL: DO UNTIL (expresso) ' faa AT que a expresso seja True ' executa bloco de comandos LOOP ' retorna para o Do Quarta, teste no final do comando com WHILE: ' faa ' executa bloco de comandos LOOP WHILE (expresso) ' ENQUANTO expresso for True Quinta, teste no final do comando com UNTIL: ' faa ' executa bloco de comandos LOOP UNTIL (expresso) 'AT que expresso seja True Em todas as maneiras podemos colocar um teste no interior do lao, para abandon-lo com o comando EXIT DO. Note que nas formas iniciadas somente com o DO, o lao ser executado pelo menos uma vez. Os Comandos Do ... Loop podem ser aninhados. Exemplo de Do ... Loop, com o teste da expresso no incio:
Do While ( Not Eof() ) ' leia a linha ' processe a linha Loop ' faa enquanto no for Fim de Arquivo
DO
DO
' se nome do ponto for nulo ' saia do lao ' fim se ' fim lao
154
Verso 2
Os Comandos LABEL, GOTO e GOSUB, devem ser evitados. Um uso importante do GOTO com o comando ON ERROR. Para obter mais detalhes sobre estes comandos, consulte a ajuda on-line.
Comandos
Um comando uma combinao de elementos do Basic, escrito de acordo com as regras de sintaxe da linguagem. Alguns podem ocorrer em qualquer parte do programa, outros no. Os comandos so os responsveis pela funcionalidade dos procedimentos. Normalmente um comando cabe numa s linha, caso contrrio podemos usar o sublinhado, para indicar que o comando continua na prxima linha. O caractere de continuao no pode ser usado dentro de uma cadeia (string). Veja o exemplo: Informe$ = Esta uma linha de comando que continua + _ na prxima linha Numa mesma linha, podemos escrever mais de um comando, usando o caractere dois pontos, como separador de comandos. Abaixo, temos trs comandos de atribuio: i = 0 : j = 1 : sinal = False
Sub-rotinas
Sub-rotinas devem ser definidas pelo comando SUB ... END SUB, da seguinte maneira: SUB Nome_Da_Rotina ( Lista_De_Parmetros ) '
Introduo ao OpenOffice.org Basic 155
Verso 2
' Declarao de variveis Locais ' Comandos da sub-rotina ' END SUB A Lista_de_Parmetros, so os valores, separados por vrgula, que a rotina recebe para executar o seu trabalho e devem conter a especificao de tipo. Por exemplo: SUB MinhaSub (par1 As Integer, par2 As Double, par3 As String) Se um dos parmetros for uma varivel da macro o seu nome na lista da sub-rotina pode (e deve) ser diferente do nome da varivel na macro. Exemplo de sub-rotina que troca os valores de duas variveis:
SUB TrocaValores ( valor1 As Double, valor2 As Double) ' Dim temp As Double ' temp = valor1 valor1 = valor2 valor2 = temp ' Note que apesar de no retornar valores, as variveis passadas ' como parmetros foram alteradas e estas alteraes sero ' visveis na rotina que chamar TrocaValores ' END SUB
O comando EXIT SUB pode ser usado dentro de uma sub-rotina para abandon-la imediatamente.
Funes
A definio de uma funo feita entre os comandos FUNCTION ... END FUNCTION, como abaixo: FUNCTION NomeFuncao (ListaParametros) As TipoRetornado ' declarao das variveis locais
156
Verso 2
END FUNCTION Note que uma funo retorna o valor de uma expresso numa varivel de nome igual ao nome da funo. O comando EXIT FUNCTION pode ser usado dentro de uma funao para abandon-la imediatamente. Exemplo de uma funo que calcula o volume de uma esfera, a partir do seu raio:
FUNCTION VolumeEsfera ( raio As Double ) As Double ' Dim diametro As Double ' diametro = 2 * raio VolumeEsfera = (PI / 6) * diametro ^ 3 ' NOTE: nome da funo VolumeEsfera; nome da varivel: VolumeEsfera ' END FUNCTION
Passagem de Parmetros
A passagem de parmetros para sub-rotinas e funes pode ser feita de duas maneiras, por referncia (padro) ou por valor. Quando um parmetro (varivel) passado por referncia, qualquer alterao em seu contedo ser refletida na rotina chamadora. Se a passagem for por valor, as alteraes na varivel sero descartadas quando o procedimento terminar a sua execuo e o valor original ser preservado. Matrizes so passadas sempre por referncia. Para passar um parmetro por valor, na definio do procedimento, use a palavra BYVAL, antes do nome do parmetro, ou, se BYVAL omitida, coloque a varivel entre parnteses, na chamada, veja abaixo:
SUB ImprimePonto (BYVAL cadeia$, X#, Y#) cadeia = Ltrim$(Rtrim$(cadeia) + , + Str$(X) + , + Str$(Y) Print cadeia ' a mudana em cadeia, ser descartada no trmino da Sub END SUB
157
Verso 2
Chamada de Procedimentos
A chamada a um procedimento depende do seu tipo, se sub-rotina ou funo. Como uma subrotina no retorna valores, ela no precisa ser usada como parte de uma expresso. J uma Funo (sempre retorna um valor), deve ser usada numa expresso. Formas de chamadas de sub-rotina: ' Usando o comando CALL com ou sem parnteses CALL ImprimePonto (nomePonto, coordX, coordY) CALL ImprimePonto nomePonto, coordX, coordY ' Sem o comando CALL, com ou sem parnteses. ImprimePonto (nomePonto, coordX, coordY) ImprimePonto nomePonto, coordX, coordY Se a sub-rotina no tiver parmetros no preciso usar os parnteses. Formas de chamada de funes: ' chama a funo areaCirculo e armazena o valor da area na variavel areCirc areCirc = areaCirculo (raio) ' chama 2 funcoes, areaCirculo ( ) e Str$ ( ) o valor retornado ser atribudo a cadeia cadeia = Str$( areaCirculo ( raio ) ) ' chama 2 funcoes, Sqr ( ) e Distancia ( ) o valor retornado ser atribudo a raizDist raizDist = Sqr ( Distancia ( x1, y1, x2, y2) ) Exemplo de chamadas de sub-rotinas e funes:
Sub chamadaProcedimentos Call UneCadeiasSub ("Meu ", "exemplo sub 1") Call UneCadeiasSub "Meu ", "exemplo sub 2" UneCadeiasSub ("Meu ", "exemplo sub 3") UneCadeiasSub "Meu ", "exemplo sub 4" ' Dim cad$ cad$ = UneCadeiasFunction$ ("Meu ", "exemplo function 1") MsgBox cad$ End Sub Sub UneCadeiasSub ( cad1$, cad2$ ) MsgBox (cad1$ + cad2$) End Sub Function UneCadeiasFunction$ ( cad1$, cad2$ ) UneCadeiasFunction$ = cad1$ + cad2$ End Function
158
Verso 2
Neste exemplo, a sub-rotina principal chamadaProcedimentos ( a rotina que deve ser executada), ela chama a Sub UneCadeiasSub e a funo UneCadeiasFunction, ambas definidas pelo programador. As quatro formas de chamada da Sub UneCadeiasSub so equivalentes.
159
Mais informaes
Verso 2
10 Mais informaes
10.1 Na rede
OpenOffice.org : O lar do OpenOffice.org http://www.openoffice.org http://www.openoffice.org.br Projeto de Documentao do OpenOffice.org: http://documentation.openoffice.org OpenOffice.org for Developers http://website.openoffice.org/developer Este o local para quem est interessado em desenvolvimento com o OpenOffice.org. Aqui, voc encontra:
OpenOffice.org 1.0.2 Developer ' s Guide (~ 12 Mb ) Manual de Referncia da API do OpenOffice.org (~ 8 Mb ) StarOffice 6.0 Basic Programmer ' s Guide ( ~ 1 Mb ) StarOffice 5.2 Programmer ' s Tutorial (~ 1 Mb ) Exemplos do Developer ' s Guide (~ 1 Mb )
OOoDocs.Org http://www.ooodocs.org Documentao, fruns ( inclusive sobre Macros) e notcias do OpenOffice.org. OOOForum.Org http://www.oooforum.org Fruns do OpenOffice.org , inclusive sobre Macros e API. OOExtras http://ooextras.sourceforge.net Repositrio de modelos, macros e assistentes para o OpenOffice.org. Baixe todas as macros e estude o cdigo fonte para aprender mais. Pitonyak.org www.pitonyak.org/ Andrew Pitonyak e seus colaboradores merecem a nossa gratido. Esta pgina contm um excelente documento sobre macros e sobre a linguagem Basic. Consulte-a periodicamente. EDV Systeme Kienlein http://kienlein.com/pages/oo.html
160
Verso 2
Mais informaes
Contm o DevGuide, com exemplos do Developer's Guide e o mdulo Inspect uma excelente ferramenta para anlise de objetos. Outro achado o DbMonitor, um aplicativo OOo Basic completo, para acesso a Bancos de Dados.
161
Mais informaes
Verso 2
10) Mais links de informaes e agradecimentos. Em 06/07/2003: Publicao da Introduo na HomePage www.ioobasic.kit.net . Em 02/07/2003: Publicao da verso 1, no site do OpenOffice.org Projeto Brasil. Em 02/04/2003: Incio da Introduo ao OpenOffice.org Basic.
162
Verso 2
11.1 Crditos
Autor do layout grfico do modelo: Mirto Silvio Busico <m.busico@ieee.org> Autor do texto explanatrio do modelo: Gianluca Turconi <luctur@openoffice.org>
11.2 Agradecimentos
A Sun Microsystems, Inc pelo apoio para a criao e desenvolvimento do OpenOffice.org. A Sun Microsystems, Inc, mais uma vez, pela disponibilizao da documentao sobre a API do OpenOffice.org, sem a qual este trabalho no seria possvel. A todos os voluntrios que, com os seus trabalhos, contribuem para o crescimento do OpenOffice.org. Aos coordenadores do OpenOffice.org Projeto Brasil, pela publicao da Introduo, principalmente, a Gustavo Buzzatti Pacheco, pelo apoio e sugestes. A Ismael Fanlo pela traduo da verso 1 deste documento para o Espanhol.
11.3 Licena
permitida a cpia, distribuio e / ou modificao deste documento, sob os termos da GNU Free Documentation License, Version 1.1 ou uma verso posterior publicada pela Free Software Foundation. Uma cpia da licena acompanha este documento, consulte o arquivo FDL.TXT. Se voc no recebeu uma cpia deste arquivo, por favor informe ao autor ou ao webmaster do site que disponibilizou este documento. Copyright 2003 Noelson Alves Duarte.
163