Hoje falarei sobre os dados para o meu projeto de iPhone e como o editei. Ele nem é um jogo, e sim um livro de receitas de coquetéis. Possui mais de 1.200 receitas em sua maioria exclusivas usando quase 400 ingredientes diferentes. É uma grande quantidade de dados para se discutir. Já existem muitos artigos que discutem como armazenar dados – XML, JSON, binário etc. No entanto, poucos discutem como editá-los. XML e JSON são ambos legíveis, mas não são fáceis de editar em grande escala. Uma ferramenta C# poderia ser escrita a partir do zero para editar os dados, mas isso parece desajeitado e um desperdício para um projeto extra.
Um amigo recomendou usar as Planilhas do Google como um editor e eu não poderia estar mais feliz com essa decisão. Digitar dados em uma planilha não é um conceito particularmente único. O que torna as Planilhas do Google legais é como é fácil de escrever uma ferramenta C# para baixar os dados. Se você não estiver familiarizado com o serviço Google Documents, então eu sugiro que dê uma olhada nele. Qualquer conta do Google, como Gmail, oferece acesso gratuito à funcionalidade básica do tipo MS Office – documentos (Word), planilhas (Excel), apresentação (Powerpoint) etc. Nenhuma das ofertas do Google possui tantas características completas ou poderosas quanto suas contrapartes de varejo da Microsoft, mas eles são todos gratuitos e “na nuvem”, para facilitar o acesso por qualquer computador habilitado na internet.
O Google fornece uma biblioteca. NET (download) para acesso programático. Com três dlls e apenas algumas linhas de código, você pode acessar uma planilha e baixar os dados. Como um bônus adicional, se você carregar os dados em tempo de execução, você pode modificar e atualizar uma planilha em tempo real. Devido ao fato de um dos meus principais objetivos consistir em fornecer informações concretas, eu fiz um projeto de exemplo rápido (download) e uma conta fictícia do Gmail para que qualquer pessoa possa baixar e executar o código real. Ele foi compilado no Visual Studio 2010 com .NET 4. Ele funciona na minha máquina e eu não ofereço mais garantias. 🙂
O projeto de demonstração levou cerca de 10 minutos para completar do início ao fim. Decidi que iria fazer uma planilha contendo desenvolvedores de jogos e jogos, e carregá-la em uma linda linha do tempo. Aqui está como ficaram os dados:
Muito simples e direto. Duas colunas com cabeçalhos, desenvolvedores na coluna A, e um número variável de jogos para a direita. Qual é o processo para analisar esses dados? Aqui está um resumo:
- Criar um serviço de nova planilha
- Definir nome de usuário e senha
- Encontrar a planilha correta
- Localizar a planilha correta
- Iterar sobre células
E aqui está o código em si.
private void ImportFromGoogle()
{
// Login/Password to GMail Account
string userName = "username_goes_here";
string password = "password_goes_here";
// Name of spreadsheet and worksheet to access
string spreadsheetName = "Example Spreadsheet";
string worksheetName = "Example Worksheet";
// Connect to google's service with login/password
SpreadsheetsService service = new SpreadsheetsService( spreadsheetName );
service.setUserCredentials( userName, password );
// Query spreadsheets
SpreadsheetQuery spreadsheetQuery = new SpreadsheetQuery();
SpreadsheetFeed spreadsheetFeed = service.Query(spreadsheetQuery);
// Loop over all spreadsheets
foreach( SpreadsheetEntry spreadsheet in spreadsheetFeed.Entries )
{
// Check if this the spreadsheet we want
if( !spreadsheetName.Equals(spreadsheet.Title.Text, StringComparison.OrdinalIgnoreCase) )
continue;
// Query worksheets
AtomLink worksheetLink = spreadsheet.Links.FindService(GDataSpreadsheetsNameTable.WorksheetRel, null);
WorksheetQuery worksheetQuery = new WorksheetQuery(worksheetLink.HRef.ToString());
WorksheetFeed worksheetFeed = service.Query(worksheetQuery);
// Loop over worksheets
foreach( WorksheetEntry worksheet in worksheetFeed.Entries )
{
// Check if this is the worksheet we want
if( !worksheetName.Equals(worksheet.Title.Text, StringComparison.OrdinalIgnoreCase) )
continue;
// Get cells
AtomLink cellLink = worksheet.Links.FindService(GDataSpreadsheetsNameTable.CellRel, null);
CellQuery cellQuery = new CellQuery(cellLink.HRef.ToString());
CellFeed cellFeed = service.Query(cellQuery);
AtomEntryCollection cellEntries = cellFeed.Entries;
// Need to determine what column is what. Hardcoded for example.
int devOffset = 0;
int gameOffset = 1;
// Loop over all entries finding the first entry on each row
for( int i = 0; i < cellEntries.Count; ++i )
{
// Continue if this entry is not the first entry of a row (and not the first row)
CellEntry baseEntry = cellEntries[i] as CellEntry;
if( baseEntry.Row == 1 || baseEntry.Column != 1 )
continue;
// Cell containing developer name
CellEntry devCell = cellEntries[i+devOffset] as CellEntry;
// Create a node for the tree view for this developer
TreeNode devNode = new TreeNode(devCell.Value);
// Loop over all games associated with this developer
int gameIndex = (i + gameOffset);
while( true )
{
// Get game cell, if it's on a new row we're done with this developer
CellEntry gameCell = cellEntries[gameIndex] as CellEntry;
if( gameCell.Row != devCell.Row )
break;
// Add game to developer tree node
devNode.Nodes.Add( new TreeNode(gameCell.Value) );
// Increment and validate index
++gameIndex;
if( gameIndex >= cellEntries.Count )
break;
}
// Add developer node to list view
TV_Devs.Nodes.Add(devNode);
}
}
}
}
O que conseguimos depois de tudo isso? Algo assim:
Voilà! A planilha de dados foi transformada, com sucesso, em dados C#. Esses novos e convenientes dados podem depois se tornar a parte central do nosso conteúdo.
Alguns pontos dignos de nota aqui. Quando você pegar o objeto CellEntries, ele contém uma lista simples de células não vazias. Isso requer que os dados sejam formatados apropriadamente. Não é um sistema que eu recomendo para o desenvolvimento AAA, mas para um projeto solo eu o considerei perfeitamente aceitável. Se você quiser fazer isso em seu próprio projeto, então há duas etapas especiais a se seguir.
- Inclua as três dlls do Google – cliente, extensões e planilhas. Estes podem ser encontrados no meu projeto demo ou a partir da biblioteca Google.
- Mude a meta do seu projeto do framework “. Net Framework Client Profile 4” para “. NET Framework 4”, pois isso permite acesso ao framework System.Web, que é necessário para ligar as dlls.
Mantendo meu foco no mundo real, aqui está como eu usei esse conceito no meu projeto de iPhone. Uma entrada de receita padrão parecida com esta:
Ela define uma boa quantidade de informações, incluindo um número variável de etapas da receita. Mais de 1.200 dessas receitas estão carregadas, além de listas separadas de objetos de cristal, tipos de bebidas, tipos de medição, dicas especiais, ingredientes e receitas em edição lite. Após a importação, os dados são validados em busca de erros de digitação, duplicatas e entradas inválidas. Os dados são então triturados convertendo a maioria dos valores de string em ids inteiros. Finalmente, eles podem ser exportados para qualquer formato de arquivo que eu desejar para ser carregado na plataforma do usuário. Aqui está uma foto da minha ferramenta para lidar com tudo isso.
Isso foi o que eu fiz para o meu projeto e eu espero que pelo menos alguém considere isso útil.
?
Texto original disponível em http://www.altdevblogaday.com/2011/04/25/google-spreadsheet-as-a-data-editor/