29 мар. 2010 г.

Ежедневник + Финансовый контроль в одном флаконе.

Цель: Контроль финансовой стороны подручными средствами в любой точки мира =)

Дано: Google Календарь и Google Документы (о версиях сия титан умалчивает, да оно вроде и не критично )

Необходимые требования:

  • Интернет
  • Браузер
  • Учетку у Google
  • собстн всё ...



Решение:
Столкнулся с мыслью держать под контролем свой финансовый гаманок.

Мысль та неплохая! Согласитесь, здравая ведь! =)

Так вот, хотелось бы иметь доступ к записям в любой точке.

Флешки, скажите вы, портабле программс ... ну как бы да, но не то всё это... нет гибкости что ли, где винда, где линь - искать что та мульти, а еще и флешки частенько забываются ...

И что же … ? Пользуюсь практически ежедневно приложением "Google Календарь", записи встреч, дел, прочей ерундовины. Весьма удобная штука заметить должен Вам, так к слову, она еще и уведомления шлет на телефон СМСкой ;)

Так вот, думаю, а почему бы нет, буду записывать все РАСХОДЫ/ПРИХОДЫ в календарь под грифом Bank (издевки на счет грифа оставим при себе, что пришло на ум, то и записал =) ), а знаки в завершении ключевого слова [+-] для себя, некая визуализация расходов/приходов.

Внутри события пояснения с статьями расходов, как видим из (рис. 2), каждая конкретная цифра отделена переносом строки, характер записей таков:
[+-][цифра][пробел][Категория][:][Комментарий][перенос строки]
[+-][цифра][пробел][Категория][:][Комментарий][перенос строки]




Где, знаки [+-][Категория][:][Комментарий] вовсе не обязательны, но без знака [-] не записать расходы, а без [Категория] не вычислить самые удельные статьи, ну и [Комментарий] – вспоминать потом замучаемся, на что же было ухезано 1200 деревяненьких после бани … =)

Получилось что-то типа рис. 1 и рис. 2




Да … факт прихода/расхода зафиксирован … но наглядность, а уж фулл контроль напрочь отсутствует, вернитесь к (рис. 1) … кроме "синеньких" заголовков . Не совсем то что хотели.

Чуть позже изучая возможности сервиса "Google Документы", а именно в плане работы с таблицами, обнаружил для себя приятную весчь (рис. 3)

Сценарии … хм …


Как оказалось сценарии это нечто иное как Google Apps Script, который всеми своими прелестями напоминает тот же самый JavaScript. Похвастаться что виртуоз сия "языка" не могу, но его фишка в том что у него уже встроен API к большинству своих же продуктов (http://www.google.com/google-d-s/scripts/overview.html) ...

Осталось дело за малым, сделать формирование данных в таблице сервиса "Google Документы" средствами сия чудо скриптового языка.

Сказано – Сделано! Сия результат работы смотрим на (рис.4)



Что имеем:
Имя вкладки есть начала периода – конец периода автоматически ставится последний день месяца указанного в названии вкладки. И так, для марта сия (2010) года смотрим (рис.5)

Далее, сортируем по убыткам … смотрим расходные статьи снова на (рис.5)



На счет графиков, наверное возможно, у меня не получилось, ибо не хотел копаться, то что нужно было уже есть, графики ужо баловство какое то =)


Итого, под рукой всегда календарь (благо GPRS худо бедно, но доступен практически везде), под рукой в любой момент Ваш финансовый документ, разбитый по месяцам, вы счастливы и тащитесь от того что имеет контроль над своими сбережениями! =)



Сам исходник:

function getEventCalendar() {
var strKey="bank"; /* Key Event's */
var C = CalendarApp.openByEmailAddress("Dmitriy.V.Biryukov@gmail.com"); /* Whose calendar (Login) */

/* Date of start and completion of the title active sheet */
var today=new Date();
today.setTime(Date.parse( SpreadsheetApp.getActiveSheet().getName() ));
var endday = new Date(today.getFullYear(), (today.getMonth()+1), (today.getDate()-1));

/* Receive events from the calendar */
var Cevents = C.getEvents(today, endday);


var pos=1; /* with a line going insert document */
var prefix=''; /* not change */
var cat=[];

SpreadsheetApp.getActiveSheet().clearContents();
SpreadsheetApp.getActiveSheet().clearFormats();
SpreadsheetApp.getActiveSheet().getRange("A"+pos+":I"+SpreadsheetApp.getActiveSheet().getMaxRows()).setFontSize(8);

/* Form a title */
SpreadsheetApp.getActiveSheet().getRange("A"+pos+":I"+pos).setBackgroundColor('#000000');
SpreadsheetApp.getActiveSheet().getRange("A"+pos+":I"+pos).setFontColor('#ffffff');
var Title=[['Дата', 'Приход', 'Расход', 'Категория', 'Комментарий', 'Прогрессия', '', 'Категория', 'Сумма']];
SpreadsheetApp.getActiveSheet().getRange("A"+(pos)+":I"+(pos)).setValues(Title);


/* Formation document */
for (var i = 0; i < Cevents.length; i++) {
var title=Cevents[i].getTitle();
if (!(title.search(/bank/i)==-1)) {
var rows = Cevents[i].getDescription().split("\n");
for (var s = 0; s < rows.length; s++) {
var row = rows[s].trim();
if (row) {
pos++;
/* Find Sum and Comment: -5000 Shop $)) */
var patt=new RegExp(/^([-+]?[\ ]*\d+)(.*)$/);
var str=patt.exec(row);

if (str[1]) {
var StartTime = Cevents[i].getStartTime();

/* Cut sign [+ or space]*/
str[1] = str[1].replace(/^\+|\ {1,}/g, "");

/* Clear data and format current row */
SpreadsheetApp.getActiveSheet().getRange("A"+(pos)+":F"+(pos)).setFontSize(8);

/* Insert Data */
StartTime = StartTime.getDate()+'.'+(StartTime.getMonth()+1)+'.'+StartTime.getFullYear();
var CatCom = str[2].trim().split(":",2);
if (!CatCom[1]) CatCom[1]="";
if (typeof(cat[CatCom[0]])== 'undefined') cat[CatCom[0]]=0;
cat[CatCom[0]]+= parseFloat(str[1]);

if ((str[1]>0)) SpreadsheetApp.getActiveSheet().getRange("A"+(pos)+":E"+(pos)).setBackgroundColor('#e8eef7');

SpreadsheetApp.getActiveSheet().getRange("A"+(pos)).setValue(StartTime);
SpreadsheetApp.getActiveSheet().getRange(((str[1]>0) ? "B" : "C") +pos).setValue(str[1]);
SpreadsheetApp.getActiveSheet().getRange("D"+(pos)).setValue(CatCom[0]);
SpreadsheetApp.getActiveSheet().getRange("E"+(pos)).setValue(CatCom[1]);
SpreadsheetApp.getActiveSheet().getRange("F"+(pos)).setFormula('='+prefix+'(B'+pos+'+C'+pos+')');

prefix='F'+(pos)+'+';
}
}
}
}
}

/* Insert Total row */
pos+=2;

SpreadsheetApp.getActiveSheet().getRange("A"+(pos)+":F"+(pos)).setBackgroundColor('#000000');
SpreadsheetApp.getActiveSheet().getRange("A"+(pos)+":F"+(pos)).setFontColor('#ffffff');

SpreadsheetApp.getActiveSheet().getRange("A"+(pos)).setValue('Итого:');
SpreadsheetApp.getActiveSheet().getRange("B"+(pos)).setFormula('=SUM(B1:B'+(pos-1)+')');
SpreadsheetApp.getActiveSheet().getRange("C"+(pos)).setFormula('=SUM(C1:C'+(pos-1)+')');
SpreadsheetApp.getActiveSheet().getRange("F"+(pos)).setFormula('=(C'+pos+'+B'+pos+')');

pos=2;
for(name in cat){
SpreadsheetApp.getActiveSheet().getRange("H"+(pos)).setValue(name);
SpreadsheetApp.getActiveSheet().getRange("I"+(pos)).setValue(cat[name]);
pos++;
}


}


String.prototype.trim = function() {return this.replace(/^\s+|\s+$/g,"");}


На этой счастливой ноте и закруглимся.

Комментариев нет:

Отправить комментарий