Arquivo da categoria: Desenvolvimento

Novidades, críticas, comentários sobre o desenvolvimento e programação de sistemas, assunto que tanto agrada este autor.

Selenium – Brincando com as configurações do Chrome, Polymer e ShadowRoot

Uau! Mas o que é tudo isso? Sim caro leitor, quando você entra do mundo do Web Scrapping, a palavra Web traz um quinquilhão de coisas junto com ela, de benefícios a dores de cabeça.

A Web não pára e apesar desta frase ser um baita clichê, ela é assustadoramente verdadeira. Vou dar um exemplo do porquê. Tem alguns anos um treco HTML5 foi lançado. Já ouviu falar dele? Pois é, junto com ele, uma tonelada de novas tags HTML e apis Javascript também vieram. Seus scripts Selenium precisaram ser atualizados.

Vida que segue e… boom! Mais atualizações. Duas delas foram mencionadas no título e é sobre elas que falarei aqui.

Eu só queria extrair uma configuração do Chrome

Sim, tudo o que eu queria era extrair uma configuração do Google Chrome instalado na máquina do usuário. A parte fácil é que essa página de configurações é um HTML exposto sob a URL chrome://settings. Ótimo! É só dar um get nessa URL e começar a mágica.

O problema é, bem, esse é o Google Chrome, criado e mantido pelo Google, provavelmente a empresa que mais expõe e propõe inovações para especificações Web atualmente. Não surpreendentemente, a página de configurações usa um bocado de coisas novas (só precisa funcionar no Chrome mesmo), entre elas, o ShadowRoot e Polymer.

Não vou me aprofundar no que cada um desses carinhas é além de uma breve explicação.

ShadowRoot

É uma espécie de elemento HTML que cria um novo contexto a partir dele. Você pode pensar nele como um iframe + ajax com muita esperteza embutida, criado para separar contextos da hierarquia. Para mais informações: https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot

Polymer

É basicamente um padrão proposto pelo Google para criação de elementos HTML personalizados. Se você sabe algo de XML, é exatamente isso, só que, cada elemento que você criar, ganha uma nova representação visual numa página HTML. Já há vários elementos criados nesse padrão. Para mais informações: https://www.polymer-project.org/

Como não poderia ser surpresa, a página de configurações do Google está recheada dessas duas coisas.

E o Selenium nisso tudo?

Bem, primeiro deixe-me explicar porque resolvi fazer tudo isso. Primeiro, porque todo programador teimoso gosta de resolver um problema chato e difícil. Segundo, tanto o ShadowRoot como o Polymer uma hora se tornarão largamente utilizados no mercado. Resolver esse problema agora me traria um melhor entendimento sobre o assunto e me prepararia para futuro. Vamos lá.

Mas calma, mas porque isso é tão difícil com o Selenium? O XPath resolve tudo para mim! Aí é que está o problema. Não resolve. A biblioteca atual do Selenium (não só VBA, mas todas as outras, já que elas dependem do driver para implementar funcionalidades) não suporta esses tipos de elemento.

O FindElementByTag simplesmente ignora tags criadas com Polymer e o ShadowRoot precisa ser explicitamente declarado ou expandido antes de ser possível acessar qualquer elemento dentro dele. Por sorte, há como resolver esse problema, com muito suor.

Expandindo o ShadowRoot

O ShadowRoot é basicamente o primeiro filho de uma determinada tag. O Javascript lhe dá uma ajuda nisso, aliás é o único meio no momento.

Supondo que você encontro este elemento:

....
</p>
<div id="id"><p>
#shadow-root
	</p>
<div id="outroId"></div>
<p>
</div>
<p>
...

Infelizmente, um driver.FindElementById(“outroId”) retornará nulo se você não expandir o ShadowRoot antes. Como fazer isso? Em VBA:

Set divId = driver.FindElementById("id")
Set shadowRoot = driver.ExecuteScript("return arguments[0].shadowRoot", divId)
Set divOutroId = shadowRoot.FindElementById("outroId")

A primeira linha é mais do que clara.
A segunda faz a mágica de expandir o ShadowRoot que pertence à primeira div e o retorna para a variável shadowRoot.
A terceira, já de posse o elemento que representa o ShadowRoot, aplica o FindElementById para a captura do elemento procurado, desta vez retornando o de forma válida.

Capturando tags Polymer

Elementos Polymer como explicado anteriormente, são basicamente tags HTML, porém, personalizadas. Portanto, ao invés de ter algo assim:

<div id="endereco"><p>
	</p>
<div id="rua">Rua Principal</div>
<p>
	</p>
<div id="numero">1000</div>
<p>
	</p>
<div id="bairro">Capital</div>
<p>
</div>

Teriámos algo assim:

<endereco>
	<rua>Rua Principal</rua>
	<numero>1000</numero>
	<bairro>Capital</bairro>
</endereco>

É de falto mais semântico, legível e auto-explicativo. E segundo exemplo não existe na especificação HTML e um navegador não sabe reconhecê-lo, mas o Polymer torna isso possível.

O porém para nós, nobres web scrappers, a coisa não é tão simples. Veja que pela auto declaração dos elementos pela sua própria semântica, não há necessidade de ids ou outros atributos identificadores. Onde antes faríamos um:

driver.FindElementById("rua")
'ou
driver.FindElementsByTag("div")(2)
'ou
driver.FindElementByXPath("//div[@id=""rua""]")

Com Polymer faríamos:

driver.FindElementByTag("rua")

Mas não! O Selenium não sabe reconhecer esse tipo de tag! Qualquer tentativa de fazê-lo com FindElementByTag ou FindElementByXPath falhará. Como resolver isso? Assim:

AVISO: O FindElementByTag curiosamente funciona para o primeiro elemento da cadeia, ou seja, um elemento pai. Por isso, o código abaixo usa o FindElementByTag no elemento endereço sem maiores erros.

Set endereco = driver.FindElementByTag("endereco")
Set rua = driver.ExecuteScript("return arguments[0].querySelectorAll('rua')[0];", endereco)

Mais uma vez, o Javascript resolvendo o problema. A variável rua é um WebElement válido a partir de agora.

Um caso real – Obtendo o diretório local de downloads do Chrome

Pois é, essa simples necessidade gerou todo o artigo acima. Basimente, precisei navegar até a página de configurações do navegador do Google, toda feita usando ShadowRoot e Polymer e extrair a informação. Como disso anteriormente, é uma página HTML, por isso, convido-o a acessar a mesma e olhar o código fonte.

No fim, o código que executa a proeza é:

Dim driver As WebDriver
 
Sub ObtemCaminhoDownload()
    Dim shadowRoot As WebElement, _
        settingsUI As WebElement, _
        main As WebElement, _
        settingsBasicPage As WebElement, _
        advancedPage As WebElement, _
        settingsSection As WebElement, _
        settingsDownloadsPage As WebElement, _
        settingsAnimatedPage As WebElement, _
        neonAnimatable As WebElement, _
        defaultDownloadPath As WebElement
 
    Set driver = New ChromeDriver
    driver.Get "chrome://settings"
    Set settingsUI = driver.FindElementByTag("settings-ui")
    Set shadowRoot = driver.ExecuteScript("return arguments[0].shadowRoot", settingsUI)
    Set main = shadowRoot.FindElementById("main")
    Set shadowRoot = driver.ExecuteScript("return arguments[0].shadowRoot", main)
    Set settingsBasicPage = driver.ExecuteScript("return arguments[0].querySelectorAll('settings-basic-page')[0];", shadowRoot)
    Set shadowRoot = driver.ExecuteScript("return arguments[0].shadowRoot", settingsBasicPage)
    Set advancedPage = shadowRoot.FindElementById("advancedPage")
    Set settingsSection = driver.ExecuteScript("return arguments[0].querySelectorAll('settings-section')[2];", advancedPage)
    Set settingsDownloadsPage = driver.ExecuteScript("return arguments[0].querySelectorAll('settings-downloads-page')[0]", settingsSection)
    Set shadowRoot = driver.ExecuteScript("return arguments[0].shadowRoot", settingsDownloadsPage)
    Set settingsAnimatedPage = driver.ExecuteScript("return arguments[0].querySelectorAll('settings-animated-pages')[0];", shadowRoot)
    Set neonAnimatable = driver.ExecuteScript("return arguments[0].querySelectorAll('neon-animatable')[0];", settingsAnimatedPage)
    Set defaultDownloadPath = neonAnimatable.FindElementById("defaultDownloadPath")
    Debug.Print defaultDownloadPath.Text
End Sub

Basicamente, usando todas os truques citados acima. Todas as outras tentativas, usando os caminhos tradicionais não funcionarem, sendo esse o único caminho atual.

Vai ser sempre assim?

Não. Encontrei várias referências de que o time dos drivers está trabalhando para adicionar métodos nativos para tratar com ShadowRoot e fazer os métodos baseados em tags suportarem o Polymer. Não há previsão de quando isso será lançado, mas é um trabalho em andamento e a complexidade mostrada acima pode não ser mais necessária, o que será um alívio.

VBA e VB.NET – Um comparativo (injusto)

E eis o primeiro vídeo da série! Vamos ver o que o .NET tem de bom, principalmente quando se trata de ListView… ou melhor, DataGridView 🙂

Arquivos utilizados no vídeo ► http://www.tomasvasquez.com.br/forum/…

Download do Visual Studio Community ► https://www.visualstudio.com/vs/older…

Entrevista Karen Abecia (RubberDuck) ► https://www.youtube.com/watch?v=7IE9w…

Acesse também

BLOG ► https://www.tomasvasquez.com.br/blog/
FÓRUM ► http://www.tomasvasquez.com.br/forum/
CURSO ONLINE DE C# ► http://www.tomasvasquez.com.br/cursoc…

Aqui também!

FACEBOOK ► https://www.facebook.com/tomasvaquezs…
TWITTER ► https://twitter.com/tomamais
GOOGLE+ ► https://plus.google.com/+TomasvasquezBr/

Roteiro, apresentação, edição, etc, etc ► eu mesmo 🙂

Do VSTO ao Office Add Ins em Javascript – Minhas Impressões

Fazia tempo que não tinha um bom motivo para “escrever um artigo”. Ultimamente gravar e publicar vídeo tutorias tem sido cada vez mais fácil (valeu Youtube) e o pessoal parece gostar do formato.

Com a toada em que a internet se encontra, decidi deixar o título simples. Nada de click bait. Nada de “O VBA vai acabar” ou “VBA, a hora da verdade”. Isso me irrita tanto que não tenho coragem de fazê-lo com vocês, pelo menos até hoje.

Indo ao assunto, estamos falando de VBA, ou melhor, desenvolvimento para a plataforma Office, depois de trabalhar quase 17 anos com essa notável ferramenta, a qual me levou a ser o profissional que sou hoje. Não sou o cara mais bem sucedido do mundo, mas estando bem empregado no mesmo ramo e gostando muito do que faço diariamente, considero isso um ponto muito positivo.

Vamos ao que interessa, mas antes, as opiniões colocadas aqui são 100% minhas e têm como fontes além da vivência, longas conversas com colegas que manjam do assunto, incluindo MVPs em Office. E sim, isso foi uma carteirada. 🙂

Público Alvo

O público que pretendo atingir é o de programadores/usuários VBA e também a comunidade engajada no seu (bom) uso.  Se por um acaso você é um programador não VBA mas se interessa pelo assunto, bem, meus parabéns e seja bem vindo!

Desenvolvimento para Office: Como estamos atualmente?

Tendo em mente que estou escrevendo este artigo no primeiro semestre de 2017, o que vou escrever aqui pode mudar muito nos próximos meses, quem dirá nos próxmos anos. O momento atual pode ser definido da seguinte forma:

  • O VBA ainda existe, vem como padrão na instalação do Office 2016, mas não é atualizado seriamente desde 1999. Houveram algumas funções adicionadas no Office 2003, mas nada sério.
  • A investida atual da Microsoft para desenvolvimento Office é o Office Add Ins, permitindo criar “Apps” que são embutidos no Office via barra de tarefas (aquela que aparece à direita), mas criadas em Javascript e distribuídas via Office Store.
  • O VBA está de fato cada vez mais bugado e isso só piora a cada versão.

Adicionalmente, alguns fatos precisam ser colocados para servir de base para a argumentação que farei neste texto.

O desenvolvimento para VBA está longe de acabar. Comunidades sobre o assunto só crescem e o interesse permanece estável. Abaixo podemos ver o gráfico do Google Trends que mostra o interesse na linguagem comparada ao que são suas alternativas:

Google Trends - VBA, VSTO, Office Add Ins e Interop
Google Trends – VBA, VSTO, Office Add Ins e Interop

A comparação chega a ser ridícula. Ainda que seja possível argumentar que o desenvolvimento vem caindo, é muito pouco para uma linguagem que não têm investimento algum a quase duas décadas, enquanto outras lutam para ser manter no páreo. O que não entendo é como isso pode ser ruim.

O stackoverflow.com, que é no momento “O FÓRUM” para qualquer linguagem de programação, tecnologia ou framework em uso trás os seguintes números aproximados:

  • VBA: ~80 mil menções
  • VSTO: ~12 mil menções
  • Office JS: ~1,5 mil menções

Procurar por Office Add In não conta pois ele engloba toda e qualquer tecnologia na qual se pode construir um, desde o VBA até mesmo C++.

Convenhamos, a Microsoft é muito conhecida tanto por seus grandes acertos (Office, .NET, SQL Server, Azure) como por seus inesquecíveis fracassos (Windows Milenium, Vista, Infopath, Zune, Windows Phone).

Por fim, temos o VBA firme e forte, o VSTO sabe lá onde está, o Office Add In em Javascript está engatinhando, mas não estou muito otimista sobre. Já comento mais.

Qual é o real estado do VBA?

O estado do VBA em si, desde o mercado até a ferramenta é caótico. O grande problema é que ser caótico não é necessariamente ruim.

O caos se dá pela falta de direção que um programador VBA deve tomar. No meu caso, eu comecei criando macros simples sem entender muito o que estava acontecendo, para depois sim entrar num curso de lógica de programação, que foi quando as coisas começaram a fazer mais sentido. Depois de trabalhar 3 anos descobrindo o VBA, ingressei na faculdade de Ciências da Computação e aí tudo ficou mais polido, já que tive uma visão mais abrangente de como linguagens de programação e ferramentas como ele funcionam.

Entretanto, para a maioria o caminho não é bem esse. Muitos vem de outras áreas que nada tem em relação com programação em si. Eles encontram seu próprio caminho usando o VBA porque ele permite isso. No fim, temos soluções das mais variadas criadas pelo mais variados tipos de profissionais e que entendem do negócio (quem mais faria um código para o mercado financeiro do que uma analista de finanças?) resolvendo uma série de pequenos problemas e até mesmo movendo negócios.

Onde está o problema nisso? Manutenção.

É relativamente simples criar um código, mas mantê-lo, nem tanto. O criador da proeza faz tudo que pode para fazer funcionar sem o compromisso de manter um nível decente de manutenibilidade. E se você é um deles, eu não te culpo. Você não teve a contextualização suficiente para entender a importância disso pois você não é um programador e naturalmente não deveria se preocupar em ser. Você assumiu o papel de um. Você gosta de ser um quando está criando um código, mas não quer ser quando precisa resolver um bug nele.

O resultado? Milhares (quiçá milhões) de aplicativos VBA criados precisando desesperadamente de manutenção e não há quem queira fazê-lo. Quem criou não tem disposição ou noção para tal e programadores em outras linguagens (sim, porque este programador olha para o VBA como um patinho feio, algo de segunda linha) não querem chegar perto desse tipo de código.

A facilidade de criação permitida pelo VBA é o que o faz tão forte e utilizado, mas a mesma facilidade permite que o código vire uma bagunça logo e desenhe o cenário que temos hoje. É preciso encontrar um meio termo. Uma mudança drástica como as que vem sendo propostas não tem sido a melhor escolha e matar o ecossistema pode além de causar revolta nos usuários, sacrificar um número expressivo de negócios e fazer o mercado criar alternativas.

Alô Microsoft?!?

O que aconteceu com o VSTO?

O VSTO (Visual Studio for Office) foi a primeira tentativa oficial da Microsoft de dar ao Office um desenvolvimento “sério”, antes feito através do VBA ou das bibliotecas padrão do Office manipuladas via VB6, Delphi ou C++.

Antes mesmo do VSTO, tivemos um movimento chamado Smart Documents. Era, na minha opinião, algo incrível! Você mapeava áreas de documentos Word, planilhas Excel e/ou slides no PowerPoint e adicionava inteligência a isso, como uma tradução simultânea, acesso a contratos que estivesse no contexto. Notável! Podia ser feito tanto no VB6, o que era bom para programadores VBA, como em C# ou VB.NET. Envolvia muito XML (lembra daqueles mapas de documento?) e era chato de fazer, mas o resultado era bom.

O VSTO veio incrementar isso, sendo completamente integrado ao Visual Studio, permitindo abrir o Excel e o Word dentro da ferramenta para ver o resultado quase pronto, podendo arrastar controles, datasets, conexões com o banco de dados e o que mais a ferramenta entregava. Um marco! Era bom, mas assim como a alternativa acima citada, errava num ponto crucial:

A distribuição.

Publicar um aplicativo VSTO era (e ainda é) uma epopéia, envolvendo arquivos de manifesto (mais xml), privilégios de execução, etc, etc, etc. Fazer o usuário executar uma planilha feita nessa tecnologia era tão desencorajador que o desenvolvedor parava no meio do caminho e voltava para o VBA, mesmo sabendo que isso lhe custaria abrir mão de todos os recursos do Visual Studio e das linguagens que se pode utilizar nele. E sim, o problema continua até hoje.

O VSTO evolui bem em quanto ferramenta, bibliotecas e até implementou tipos dinâmicos para fazer ser mais fácil codificar em C#, mas nada mudou na forma de entregar o produto compilado ou para facilitar a vida de quem veio do VBA.

Office mais… Javascript?

Confesso que quando li isso pela primeira vez, quase pulei da cadeira. Trazer a linguagem mais utilizada na internet para o Office seria o pulo do gato para o desenvolvimento VBA!

Mas… sim, tem o “mas”. O que a Microsoft fez foi nada mais do que manter o VSTO só que ao invés de codificar C#/VB.NET, você faz isso em Javascript. O problema da distribuição permanece.

Aliás, é pior! Você só pode construir Add-Ins e publicá-los via Office Store, ou Office App Store, ou sei lá eu o que isso seja. Nunca tinha ouvido falar disso antes de ler sobre o assunto. Se eu como criador de aplicativos Office não sabia, que dirá o usuário.

A ideia ainda me empolga, mas se o modelo de distribuição não for modificado, eu vejo para o Office JS o mesmo fim do VSTO.

O que está errado?

Há um misto de enganos. Novamente, esta é minha opinião.

A Microsoft parece estar simplesmente ignorando as forças do VBA, que penso serem principalmente as seguintes:

  • Facilitade de desenvolvimento (Visual Basic é fácil de aprender)
  • Facilidade de distribuição (Salvar arquivo, Ativar macros, pronto)
  • Ubiquidade (o VBA já está lá, queira você ou não)

Nada disso está presente nas novas soluções propostas. O VBA não é para programadores. Ele forma programadores (presente!). Comentei isso com colegas de trabalho recentemente. Ninguém que não usa Office gosta de trabalhar com ele. O Office é bom para quem o usa diariamente, os usuários. Para todo o resto, especialmente programadores, ele não agradável de se lidar.

E é o VBA que torna a manipulação de objetos do Office algo torelável. E sim, o Office não seria o que é se não fosse o VBA e já teria sido facilmente substituído por alternativas como o Google Sheets ou as finadas que vieram uma década atrás.

A decisão óbvia que não foi tomada

Pelo menos era a decisão óbvia para mim. Como programador VBA e .NET, tinha a visão clara de que uma hora seria lançado o Visua Basic .NET for Applications.

Seria perfeito! Toda aquela estrutura do VB6 seria substituída por um subset do Visual Studio e teríamos acesso a todas as vantagens da então nova plataforma .NET. Mas não foi assim.

A Microsoft focou nos desenvolvedores, tentando atraí-los para programar para o Office. Deu certo com o .NET, por isso não os culpo por adotar tal estratégia.

Mas depois de algum tempo, ficou claro a falta de adoção por quem deveria tê-lo feito, os programadores VBA. A pergunta que fica é, porque ainda insistem tanto neste caminho?

O que está por vir

Sinceramente, não faço ideia. O que dá para prever é que se a direção não mudar, nós veremos o VBA cair na velhice e deixando de ser usado por pura inviabilidade técnica, o que já está acontecendo atualmente.

E, se você é um desenvolvedor VBA, qual é a probabilidade de adotar o VSTO ou Office JS como sua alternativa quando não houver mais escolha? O que fazer? Abandonar de vez?

Alternativas

O mercado não ficou parado. Os programadores VBA não deixaram de sê-lo e aqueles que precisam manipular documentos do Office continuam fazendo-o, mas nada de VSTO.

O acesso é feito direto via Office Primary Interop Assemblies. Isso deu um ar fresco para programadores que precisam criar soluções baseadas no Office via código, apesar de todos os problemas de compatibilidade, que vem sendo resolvidos com o tempo.

Entretanto, programadores VBA mal chegam perto desse tipo de solução.

Outra alternativa que apareceu recentemente foi o Excel DNA. Ele é uma biblioteca que permite criar AddIns para Excel usando C#/VB.NET. Você codifica no Visual Studio com todo seu potencial e no final gera o assembly .net junto com o arquivo xll (addin). É uma maneira muito elegante de resolver o problema da distribuição e prova para a Microsoft que há outros caminhos. Não tenho visto ele ser atualizado recentemente, o que é uma pena. 🙁

O que mais? O Google Sheets  está vindo aí e já é possível codificar “macros” nele, e em Javascript! Até escrevi sobre isso aqui.

Não vi muito do que o Open Office está fazendo. Quem quiser comentar sobre, fique à vontade.

O que está sendo feito sobre isso?

Da Microsoft, a única certeza que tenho é que eles querem se livrar deste contexto, seja criando alternativas, seja matando o VBA, o que parece ser o caso.

Da comunidade, há um esforço enorme em espalhar o bom uso da ferramenta através de artigos e tutoriais dos mais variados tipos e autores. O material é rico e extenso. Há representantes de peso e engajados na causa do bom uso do VBA. Isso eu posso garantir que está sendo feito, e bem feito!

E o que eu vou fazer a respeito?

Até o momento, pretendo continuar compartilhando conhecimento em VBA. Ele está aí, presente, forte, ao alcance de um atalho para que qualquer profissional possa começar sem burocracia a criar seus primeiros códigos e trilhar uma carreira no mercado de programação, que foi exatamente o meu caso.

Eu tenho um sonho grande de poder criar algum tipo de alternativa ao VBA, mas no momento é um projeto muito grande para encaixar na vida. Quem quiser uma pista, esse projeto envolveria Roslyn e muito C#. É muito louco, mas quem sabe?

Outra ideia seria criar transpiladores, ou seja, ferramentas mais modernas em linguagens mais novas que produziriam código VBA. Não deixa de ser uma solução (acontece hoje com o Javascript), mas o VBA ainda estaria por lá e em pouco tempo, evoluções no mesmo seriam necessárias (como também acontece com o Javascript), o que já é um fato hoje.

Acredito ser o melhor a fazer já que não podemos mudar o produto por conta própria.

Agradecimentos

Meu agradecimento especial os integrantes do grupo Especialistas Excel e PBI, do qual tenho a honra de fazer parte e que tanto me esclarece em doses diárias de conhecimento e bom humor. 😀

C# – Instanciando uma coleção IQueryable no LINQ

A imagem não tem muito contexto, mas achei ela bonita
Imagem de efeito

Mais uma daquelas que vale pela simplicidade.

Nunca precisei muito fazer questão de instanciar uma coleção usando LINQ e Entity Framework. Normalmente até criava as instâncias sem especificar o tipo, usando var mesmo.

Bem, isso se resolvia quando você não precisa fazer muita coisa com a variável de retorno, ou quando fazia a atribuição direta, vindo da query LINQ. Mas, e quando não dá para fazer a atribuição? Você pergunta, pra quê instanciar? Eu respondo: tem horas que é necessário, por exemplo, quando hoje precisei criar uma coleção em memória sem conectá-la diretamente ao contexto, que seria serializada mais tarde (em JSON). E como a resposta seria para uma aplicacação front-end, null não é a melhor opção.

Como instanciar um IQueryable? Simples:

IQueryable listData = Enumerable.Empty<T>().AsQueryable()

Funcionou perfeitamente! Na serialização, o resultado era uma coleção vazia (“listData”: []).

Simples e economizou um buzilhão de ifs, new List e muitos níveis de complexidade ciclomática.

Fonte: http://stackoverflow.com/a/29430798/1209721

Bom proveito!