Sumário

# Serviço ScriptForge.Dictionary

Um dicionário é uma coleção de pares de chaves-itens

- A chave é uma string. Em scripts Basic, a sensibilidade a maiúsculas e minúsculas da chave é determinada na criação do dicionário. Em scripts Python, a chave é sempre sensível a maiúsculas e minúsculas.

- Itens podem ser de qualquer tipo

Chaves e itens podem ser recuperadas, contadas, atualizadas, entre outras operações.

O serviço Dicionário é semelhante ao objeto LibreOffice Basic Collection integrado, porém com mais recursos. Por exemplo, os objetos Collection não suportam a recuperação de chaves. Além disso, os dicionários oferecem recursos adicionais, como substituição de chaves, teste da existência de uma chave específica e conversão do dicionário em uma matriz de PropertyValues ou uma string JSON.

## Invocação do serviço

##### Em Basic

O exemplo a seguir cria myDict como um dicionário vazio.

        GlobalScope.BasicLibraries.loadLibrary("ScriptForge")
        Dim myDict As Variant
        myDict = CreateScriptService("Dictionary", True)
                    'As chaves diferenciam maiúsculas de minúsculas, portanto, o segundo argumento é True

É recomendado liberar recursos após o uso:

         Set myDict = myDict.Dispose()

##### Em Python

O exemplo abaixo cria uma instância vazia do serviço Dictionary e usa o método nativo do Python update para preenchê-la com os conteúdos de um objeto Python dict.

        dico = dict('A' = 1, 'B' = 2, 'C' = 3)
        # Inicialize myDict como um objeto Dictionary vazio
        myDict = CreateScriptService('Dictionary')
        # Carrega os valores de dico para dentro de myDict
        myDict.update(dico)
        myDict['D'] = 4
        print(myDict)   # {'A': 1, 'B': 2, 'C': 3, 'D': 4}
        propval = myDict.ConvertToPropertyValues()

É possível criar uma instância do serviço Dictionary usando um objeto Python dict como argumento conforme mostrado no exemplo a seguir.

        dico = dict('A' = 1, 'B' = 2, 'C' = 3)
        # Inicializa myDict com o conteúdo de dico
        myDict = CreateScriptService('Dictionary', dico)
        myDict['D'] = 4
        print(myDict) # {'A': 1, 'B': 2, 'C': 3, 'D': 4}
        propval = myDict.ConvertToPropertyValues()

Como o Python tem suporte integrado para dicionários, a maioria dos métodos do serviço Dictionary está disponível apenas para scripts Basic. As exceções são os métodos ConvertToPropertyValues e ImportFromPropertyValues, que são suportados tanto em Basic quanto em Python.

## Propriedades

Nome | Somente leitura | Tipo | Descrição
--- | --- | --- | ---
Count | Sim | Long | Número de entradas em um dicionário
Items | Sim | Array de Variants | Lista de itens como um array de uma dimensão
Keys | Sim | Array de Strings | Lista de chaves como um array de uma dimensão

As propriedades Keys (Chaves) e Items (Itens) retornam seus respectivos conteúdos, usando uma ordem idêntica. A ordem de retorno não está relacionada à ordem de inserção dos itens.

### Exemplo:

O exemplo a seguir usa a propriedade Keys para iterar sobre todas as chaves do dicionário myDict.

        Dim a As Variant, b As String
        a = myDict.Keys
        For Each b In a
            MsgBox(myDict.Item(b))
        Next b

Lista de métodos no serviço Dictionary
Add ConvertToArray ConvertToJson ConvertToPropertyValues | Exists ImportFromJson ImportFromPropertyValues Item | Remove RemoveAll ReplaceItem ReplaceKey

## Add

Adiciona um novo par chave-item ao dicionário. Retorna True se bem-sucedido.

### Sintaxe:

dict.Add(key: str, item: any): bool

### Parâmetros:

Chave: Valor de cadeia de caracteres usado para identificar o item. A sensibilidade a maiúsculas e minúsculas da chave foi determinada na criação do dicionário..

item: Qualquer valor, incluindo arrays, objetos Basic, objetos UNO, outros dicionários, etc.

### Exemplo:

          Dim NewValue As Variant
          myDict.Add("NewKey", NewValue)

Toda chave deve ser única num mesmo dicionário. Se a chave já existe no dicionário, uma exceção DUPLICATEKEYERROR será lançada. Chaves que contém espaços em branco causarão a exceção INVALIDKEYERROR.

## ConvertToArray

Armazena os conteúdos de um dicionário em um array indexado em zero com duas colunas. As chaves são armazenadas na primeira coluna e os itens são armazenadas na segunda coluna.

Se o dicionário estiver vazio, este método retornará um Array vazio.

### Sintaxe:

dict.ConvertToArray(): any[0..*, 0..1]

### Exemplo:

          Dim myDict as Variant
          myDict = CreateScriptService("Dictionary")
          myDict.Add("a", 1)
          myDict.Add("b", 2)
          myDict.Add("c", 3)
          Dim arr as Variant
          arr = myDict.ConvertToArray()
          '(("a", 1), ("b", 2), ("c", 3))

## ConvertToJson

Converte os conteúdos de um dicionário em texto no formato JSON (JavaScript Object Notation).

### Limitações

Este método suporta os seguintes tipos de dados: String, Boolean, tipos numéricos, Null e Empty. Arrays que contém desses tipos são permitidos, independente de suas dimensões. Datas são convertidas para strings, contudo datas não podem ser usadas em arrays. Outros tipos de dados são convertidos para sua representação textual usando o serviço SF_String.Represent.

### Sintaxe:

dict.ConvertToJson(indent: str = ""): str

### Parâmetros:

indent: Quando indent é um número positivo ou texto, elementos array e objetos membros são impressos usando este nível de indentação. Um valor indent negativo adicionará novas linhas sem indentação. O valor padrão de é uma string vazia "", o que leva à escolha da representação mais compacta. Se um número positivo for usado para indent, essa quantidade de espaços será adicionada por nível. Quando indent for uma string, tal como Chr(9) ou Tab(1), o caractere Tab será usado para indentar cada nível.

### Exemplo:

          myDict.Add("p0", 12.5)
          myDict.Add("p1", "a string àé""ê")
          myDict.Add("p2", DateSerial(2020,9,28))
          myDict.Add("p3", True)
          myDict.Add("p4", Array(1,2,3))
          MsgBox myDict.ConvertToJson()
          '{"p0": 12.5, "p1": "a string \u00e0\u00e9\"\u00ea", "p2": "2020-09-28", "p3": true, "p4": [1, 2, 3]}

## ConvertToPropertyValues

Armazena os conteúdos do dicionário em um array composto por objetos do tipo PropertyValues.

Cada entrada no array é um objeto com.sun.star.beans.PropertyValue. A chave é armazenada no campo Name e o item é armazenado no campo Value.

Se um dos itens for do tipo Date, ele é então convertido para um struct do tipo com.sun.star.util.DateTime. Se um dos itens for um array vazio, ele é convertido para Null. Se o dicionário for vazio, então um array vazio é retornado.

### Sintaxe:

dict.ConvertToPropertyValues(): obj[0..*]

### Exemplo:

##### Em Basic

        Dim myDict as Variant
        myDict = CreateScriptService("Dictionary")
        'Adiciona algumas propriedades ao dicionário
        myDict.Add("Color", "Blue")
        myDict.Add("Width", 20)
        'Converte para um Array de objetos PropertyValue
        Dim prop as Variant
        prop = myDict.ConvertToPropertyValues()

##### Em Python

Note que no exemplo abaixo o dicionário Python precisa ser passado como o segundo argumento do método CreateScriptService.

        myDict = dict()
        myDict["Color"] = "Blue"
        myDict["Width"] = 30
        sfDic = CreateScriptService("Dictionary", myDict)
        prop = sfDic.ConvertToPropertyValues()

Muitos serviços e métodos da biblioteca UNO recebem parâmetros representados como uma estrutura PropertyValue, a qual faz parte da API do LibreOffice.

## Exists

Determina se a chave existe no dicionário.

### Sintaxe:

dict.Exists(key: str): bool

### Parâmetros:

key: Chave a ser buscada no dicionário.

### Exemplo:

        Dim myDict as Variant
        myDict = CreateScriptService("Dictionary")
        'Adiciona algumas propriedades ao dicionário
        myDict.Add("Color", "Blue")
        myDict.Add("Width", 20)
        '(...)
        If Not myDict.Exists("Size") Then
           MsgBox "You have to provide a Size value"
        End If

## ImportFromJson

Adiciona o conteúdo de uma string JSON (JavaScript Object Notation) ao dicionário atual. Retorna True se bem-sucedido.

### Limitações

A string JSON pode conter números, texto, valores booleanos, null e arrays contendo tais tipos. Contudo, a string não pode conter objetos JSON como sub-dicionários.

Uma tentativa de converter texto em datas é feita se o item seguir um destes padrões de formato: YYYY-MM-DD, HH:MM:SS ou YYYY-MM-DD HH:MM:SS.

### Sintaxe:

dict.ImportFromJson(inputstr: str, overwrite: bool = False): bool

### Parâmetros:

inputstr: String a ser importada.

overwrite: Quando True, entradas com o mesmo nome podem existir no dicionário e seus valores são substituídos. Quando False (padrão), teclas repetidas gerarão um erro. Esteja ciente de que as chaves do dicionário não diferenciam maiúsculas de minúsculas, enquanto os nomes diferenciam maiúsculas de minúsculas em strings JSON.

### Exemplo:

        Dim s As String
        s = "{'firstName': 'John','lastName': 'Smith','isAlive': true,'age': 66, 'birth':  '1954-09-28 20:15:00'" _
            & ",'address': {'streetAddress': '21 2nd Street','city': 'New York','state': 'NY','postalCode': '10021-3100'}" _
            & ",'phoneNumbers': [{'type': 'home','number': '212 555-1234'},{'type': 'office','number': '646 555-4567'}]" _
            & ",'children': ['Q','M','G','T'],'spouse': null}"
        s = Replace(s, "'", """")
        myDict.ImportFromJson(s, OverWrite := True)
        'Os sub-dicionários "address" e "phoneNumbers" (0) e (1) são importados como valores Empty.

## ImportFromPropertyValues

Insere os conteúdos de um array de objetos PropertyValue em um dicionário. O campo Name do PropertyValue é usado como a chave do dicionário, e o campo Value contém o valor correspondente. Retorna True se bem sucedido.

### Sintaxe:

dict.ImportFromPropertyValues(propertyvalues: obj[0..*], overwrite: bool = False): bool

### Parâmetros:

propertyvalues: Array de uma dimensão contendo objetos com.sun.star.beans.PropertyValue. Este parâmetro também pode ser um único objeto PropertyValue não contido em um Array.

overwrite: Quando for igual a True, entradas com o mesmo nome podem existir no dicionário e seus valores são sobrescritos. Se for igual a False (padrão), chaves repetidas causarão o lançamento de uma exceção. Lembre-se que as chaves dos dicionários não são sensíveis à caixa em Basic, porém elas são sensíveis à caixa em objetos PropertyValue e em dicionários nativos da linguagem Python.

### Exemplo:

Os exemplos abaixo criam um array com dois objetos PropertyValue e converte o array em um dicionário.

##### Em Basic

        Dim vProp As New com.sun.star.beans.PropertyValue
        Dim arrProp : arrProp = Array()
        vProp.Name = "Color"
        vProp.Value = "Blue"
        arrProp = SF_Array.Append(arrProp, vProp)
        vProp.Name = "Date"
        vProp.Value = CDateToUnoDateTime(Now)
        arrProp = SF_Array.Append(arrProp, vProp)
        myDict = CreateScriptService("Dictionary")
        myDict.ImportFromPropertyValues(arrProp, Overwrite := True)
        Dim keys : keys = myDict.Keys
        For Each k In keys
            MsgBox k & " - " & myDict.Item(k)
        Next k

##### Em Python

        from scriptforge import CreateScriptService
        from datetime import datetime
        import uno
        bas = CreateScriptService("Basic")
        arrProp = list()
        vProp = uno.createUnoStruct("com.sun.star.beans.PropertyValue")
        vProp.Name = "Color"
        vProp.Value = "Blue"
        arrProp.append(vProp)
        vProp = uno.createUnoStruct("com.sun.star.beans.PropertyValue")
        vProp.Name = "Date"
        vProp.Value = bas.CDateToUnoDateTime(datetime.now())
        arrProp.append(vProp)
        myDict = CreateScriptService("Dictionary")
        myDict.ImportFromPropertyValues(arrProp, overwrite=True)
        for k in myDict.keys():
            bas.MsgBox("{} - {}".format(k, myDict[k]))

## Item

Recupera um valor do dicionário com base em sua chave. Retorna o valor do item se for bem-sucedido, caso contrário retorna Empty.

### Sintaxe:

dict.Item(key: str): any

### Parâmetros:

chave: Se não existir, o valor Vazio é retornado.

### Exemplo:

O exemplo a seguir itera sobre todas as chaves do dicionário e usa o método Item para acessar seus valores.

        Dim myDict as Variant, k as Variant, allKeys as Variant
        myDict = CreateScriptService("Dictionary")
        myDict.Add("key1", 100)
        myDict.Add("key2", 200)
        myDict.Add("key3", 300)
        allKeys = myDict.Keys
        For Each k in allKeys
           MsgBox(myDict.Item(k))
        Next k

## Remove

Remove uma entrada do dicionário com base em sua chave. Retorna True se bem-sucedido.

### Sintaxe:

dict.Remove(key: str): bool

### Parâmetros:

chave: Deve existir no dicionário, caso contrário, será gerado um erro UNKNOWNKEYERROR.

### Exemplo:

        myDict.Add("key1", 100)
        myDict.Add("key2", 200)
        myDict.Add("key3", 300)
        MsgBox(myDict.Count) ' 3
        myDict.Remove("key2")
        MsgBox(myDict.Count) ' 2

## RemoveAll

Remove todas as entradas do dicionário. Retorna True se bem-sucedido.

### Sintaxe:

dict.RemoveAll(): bool

### Exemplo:

        myDict.Add("key1", 100)
        myDict.Add("key2", 200)
        myDict.Add("key3", 300)
        MsgBox(myDict.Count) ' 3
        myDict.RemoveAll()
        MsgBox(myDict.Count) ' 0

## ReplaceItem

Substitui um item existente no dicionário com base em sua chave. Retorna True se bem-sucedido.

### Sintaxe:

dict.ReplaceItem(key: str, value: any): bool

### Parâmetros:

chave: Valor de cadeia representando a chave cujo valor será substituído. Se a chave não existir no dicionário, é gerado um erro UNKNOWNKEYERROR.

value: Novo valor do item associado ao parâmetro key.

### Exemplo:

        myDict.Add("a", 1)
        MsgBox(myDict.Item("a")) ' 1
        myDict.ReplaceItem("a", 100)
        MsgBox(myDict.Item("a")) ' 100

## ReplaceKey

Substitui uma chave existente no dicionário por uma nova chave. O valor do item permanece inalterado. Retorna True se bem-sucedido.

### Sintaxe:

dict.ReplaceKey(key: str, value: str): bool

### Parâmetros:

chave: Valor de cadeia representando a chave a ser substituída. Se a chave não existir no dicionário, é gerado um erro UNKNOWNKEYERROR.

valor: Valor da string para a nova chave. Se a nova chave já existir no dicionário, será gerado um erro DUPLICATEKEYERROR.

### Exemplo:

        myDict.Add("oldKey", 100)
        MsgBox(myDict.Item("oldKey")) ' 100
        myDict.ReplaceKey("oldKey", "newKey")
        MsgBox(myDict.Item("newKey")) ' 100

Todas as rotinas ou identificadores do ScriptForge em Basic que possuem o caractere "_" como prefixo são reservadas para uso interno. Elas não devem ser usadas em macros escritas em Basic ou em Python.

Tópicos relacionados

Serviço ScriptForge.Array

Objeto Collection

♥ Doe para nosso projeto! ♥