|
Регистр оборотов в Java (Android) | ☑ | ||
---|---|---|---|---|
0
Волшебник
модератор
29.01.17
✎
21:28
|
Пишу программу для мобильных устройств типа смартфонов/планшетов на платформе Android (язык Java) и возник вопрос про регистр оборотов.
Сразу предупреждаю, 1С Мобильное приложение не предлагать. В данном случае я просто изучаю Android и у меня нет дедлайнов. Например, нам нужны остатки по счёту на заданную дату или обороты за любой заданный период. Какова должна быть структура регистра и запросы к нему? ______________________________________________________ Я пока придумал регистр "Обороты по счетам" с измерениями "Счёт", "Месяц", "Валюта" и ресурсом "Сумма". Измерение "Месяц" хранит дату на начало месяца (этой функции — НачалоМесяца — в Java нет, пришлось запрограммировать). Теперь _____ВОПРОС_____________________________________________ Напишите SQL-запрос к таблицам регистра оборотов для выборки оборотов за _любой_ заданный период. В таблице итогов регистра должны быть итоги по месяцам (григорианского календаря, если чо). Ну и всякие другие мысли приветствуются. Помогите написать конфигурацию "Мои деньги" для Android. p.s. 1С Мобильное приложение не предлагать. Одна ваша мысль может спасти Францию! Пардон, Россию! |
|||
1
dmitryds
29.01.17
✎
21:35
|
(0) при правильной работе с SQLite скорей всего не понадобится таблица итогов, достаточно будет Group By по оборотной таблице с условием по дате.
|
|||
2
mkalimulin
29.01.17
✎
21:42
|
(0) Любой период с точностью до месяца?
|
|||
3
Волшебник
модератор
29.01.17
✎
21:51
|
(2) Любой период с точностью до дня.
|
|||
4
Garykom
гуру
29.01.17
✎
21:57
|
1. Сделать как в 1С (еще 7.7)
2. NoSQL |
|||
5
Shrek_yar
29.01.17
✎
21:58
|
(0)на гитхаб уже есть ветка?
|
|||
6
Garykom
гуру
29.01.17
✎
22:00
|
(4)+ Еще есть
3. Как в Oracle, но это напряжно с вычислительной точки зрения, им пришлось View изобретать в итоге |
|||
7
mkalimulin
29.01.17
✎
22:02
|
(3) Тогда регистр должен хранить данные с точностью до дня. Можно вообще от регистра отказаться.
|
|||
8
mkalimulin
29.01.17
✎
22:05
|
(4) Причем здесь not only SQL?
|
|||
9
Agent ООЗ
29.01.17
✎
22:06
|
1с головного мозга...какие регистры на телефоне? Мои деньги для дивизии на телефоне прапорщика..миллион записей?
Регистры только тормозят систему. |
|||
10
Garykom
гуру
29.01.17
✎
22:06
|
По сути есть всего 2 варианта и куча вольных промежуточных вариаций на тему. Все прочие всего лишь их повторяют их.
1. Храним только исходные данные, операции + и -, без итогов 2. Сразу (ну или регламентно) рассчитываем и храним всевозможные могущие потребоваться "итоги", в т.ч. итоги на каждый день. Или даже секунду, реально упрощают до на каждый одинаковый момент операции(ий). И включая всевозможные "обороты" включая оборот для каждой операции и пары операций рядом и т.д. Все прочие это промежуточные, когда к примеру храним итоги и обороты только на некие "целые" периоды (месяц и т.д.). А все дополнительные рассчитываются "на лету" по исходным операциям с прибавкой цельных "итогов" или "оборотов" для уже ранее рассчитанных и сохраненных "целых" периодов если запрос включает такие периоды целиком. |
|||
11
vde69
29.01.17
✎
22:07
|
если делать разово для себя любимого - то вполне пойдет (1)
если с замахом на универсальность - то отдельно таблицу итогов (примерно как в 1с). |
|||
12
mkalimulin
29.01.17
✎
22:08
|
(10) Третий вариант - ничего не храним в регистре.
|
|||
13
Garykom
гуру
29.01.17
✎
22:11
|
(8) http://guide.couchdb.org/draft/views.html
По сути это аналог вьюх и хранимок из обычного SQL но пишется на встроенном языке (там обычный javascript). Т.е. пишем функцию для вычисления "итогов" и "оборотов" а результат функции получается всегда "мгновенно". Потому что оно будет пересчитываться при любых изменениях данных. Идеально подходит когда много операций чтения и мало операций записи. |
|||
14
Волшебник
модератор
29.01.17
✎
22:13
|
(10)(13) Да-да. Именно то, что нужно
|
|||
15
Garykom
гуру
29.01.17
✎
22:14
|
(12) "ничего не храним в регистре" это как бы вариант 1. Неважно дублируем записи прихода/расхода из документов в отдельную сущность "регистр" или нет.
По факту обычные медленные "запросы по документам" с вычислениями итогов и оборотов требуемых на лету. Никакого дополнительного кэша нету. |
|||
16
trdm
29.01.17
✎
23:20
|
Регистр - это унификатор доступа к различным объектам.
Если документов дофига (>1) :) разных видов, то регистр предпочтительнее. ПС. Яву не трогал никогда, так что понятия не имею какой там sql. |
|||
17
mkalimulin
29.01.17
✎
23:34
|
(16) Предпочтительней, чем что?
|
|||
18
Курцвейл
30.01.17
✎
07:09
|
Кстати говоря в 1С уже(!!) можно реализовывать тн граничный случай когда Таблицы итогов не существует.
|
|||
19
Волшебник
модератор
30.01.17
✎
09:31
|
остатки на дату toDate
SELECT Account, Currency, SUM(Amount) FROM Accounts_Totals GROUP BY Account, Currency WHERE month <= TOTALS_BOUNDARY2 UNION ALL SELECT Account, Currency, SUM(Amount) FROM Accounts_Records GROUP BY Account, Currency WHERE date > TOTALS_BOUNDARY2 AND date <= toDate _____________________________________________________ где TOTALS_BOUNDARY2 - начало предыдущего месяца от toDate, т.е. поздняя граница, по которую таблица итогов по месяцам может быть полезна для выполнения подсчёта итога за заданный период. Аналогично строятся обороты за любой заданный период от fromDate до toDate, только там появляется ещё один подзапрос за неполный месяц от fromDate до начала следующего месяца. _____________________________________________________ SELECT Account, Currency, SUM(Amount) FROM Accounts_Totals GROUP BY Account, Currency WHERE month >= TOTALS_BOUNDARY1 AND month <= TOTALS_BOUNDARY2 UNION ALL //записи за неполный месяц до рассчитанного периода SELECT Account, Currency, SUM(Amount) FROM Accounts_Records GROUP BY Account, Currency WHERE date < TOTALS_BOUNDARY1 UNION ALL //записи за неполный месяц после рассчитанного периода SELECT Account, Currency, SUM(Amount) FROM Accounts_Records GROUP BY Account, Currency WHERE date > TOTALS_BOUNDARY2 AND date <= toDate" _____________________________________________________ где TOTALS_BOUNDARY1 - конец месяца от fromDate, т.е. ранняя граница, с которой таблица итогов по месяцам может быть полезна для выполнения подсчёта итога за заданный период. Если TOTALS_BOUNDARY2 < TOTALS_BOUNDARY1, то подзапрос к таблице итогов не нужен, достаточно запросов к таблице движений. Всем спасибо. Все свободны. Запросы пока не запускал, но вроде должно сработать. |
|||
20
trdm
30.01.17
✎
09:37
|
(19) > Запросы пока не запускал, но вроде должно сработать.
А визуализируешь запросы чем? в хтмл сыпешь? Есть вьювы? ПС. джава - темный лес. Но видно настала пора поднатаскаться. |
|||
21
Волшебник
модератор
30.01.17
✎
09:39
|
(20) Мне достаточно блокнота
|
|||
22
trdm
30.01.17
✎
09:50
|
(21) Я про то чем на экран смарта выводишь.
|
|||
23
Волшебник
модератор
30.01.17
✎
09:53
|
(22) Есть десктопная программа для работы с базой SQLite. В ней можно потестить запросы. Скачивается бесплатно отсюда http://www.sqlite.org/download.html
Ищем Precompiled Binaries for Windows |
|||
24
Пузан
30.01.17
✎
09:56
|
(16)(20) Казалось бы причем тут Ява и запросы к скулю? Ява само по себе, скуль сам по себе. Ява никакого собственного языка запросов не имеет. К какому скулю подключаешься, язык запросов того скул и используешь. Программисты ля...
|
|||
25
Волшебник
модератор
30.01.17
✎
09:56
|
(23)+
Не, я наврал. Ищите SQLiteManager. Их как грязи. Есть даже плагин для браузера |
|||
26
Волшебник
модератор
30.01.17
✎
09:58
|
Вот SQLite Studio от братьев-поляков. Есть интерфейс на русском
http://sqlitestudio.one.pl/index.rvt?act=download |
|||
27
Волшебник
модератор
30.01.17
✎
10:01
|
||||
28
trdm
30.01.17
✎
10:27
|
(26) Отличная софтинка!
|
|||
29
H A D G E H O G s
30.01.17
✎
10:41
|
Не забудьте про оперативные итоги
|
|||
30
Beduin
30.01.17
✎
10:44
|
(0) А ты таблицу саму уже создал для хранения?
|
|||
31
trdm
30.01.17
✎
10:47
|
+(28) Мне как раз подогрели конвертер ( http://www.prog.org.ru/topic_30882_0.html ) из *.chm в *.qch (формат хелпа Qt Assistant) а *.qch - это SQlite. И приходится разбираться с проблемками.
|
|||
32
Волшебник
модератор
30.01.17
✎
10:48
|
(30) Да. И даже проводки по ней делаются.
Есть регистр оборотов Turnovers с измерениями month, account, currency и ресурсом amount. В таблице детальных записей есть ещё date. Этой информации должно хватить, чтобы получить остатки на любую дату и обороты за любой период. |
|||
33
Волшебник
модератор
30.01.17
✎
10:49
|
(29) Для оперативных итогов (текущих остатков) есть другой регистр Accounts. Там нет измерения "месяц". Там только account, currency и ресурс amount.
|
|||
34
Beduin
30.01.17
✎
11:01
|
(32) Я про то, ты ее через андроид создавал, или в консольке sqlite?
В андроид класс есть специальный SQLiteOpenHelper, чтобы создавать и выборки делать. Мощная штука. |
|||
35
Волшебник
модератор
30.01.17
✎
11:04
|
(34) SQLiteOpenHelper, конечно, используется в самой программе для открытия/создания базы.
Далее запросы отправляются через SQLiteDatabase.rawQuery() и execSQL |
|||
36
H A D G E H O G s
30.01.17
✎
11:04
|
(33) Почему ОИ не сделать тупо отдельной записью на 3999 год?
|
|||
37
Волшебник
модератор
30.01.17
✎
11:05
|
(36) Коряво как-то
|
|||
38
Beduin
30.01.17
✎
12:01
|
(35) Я когда разбирался с этим не понял, как еще одну базу создать?
Может ли приложение иметь две базы в своем хранилище. |
|||
39
Salimbek
30.01.17
✎
12:28
|
(0) Давно-давно был ряд любопытных статей на Кинт-е. Бегло, по памяти, опишу, что помню...
Табличка с полями "С", "ПО", реквизитами и ресурсами. Когда пишется новая запись, то создаем ее С - 01.01.0001 ПО 01.01.9999. Когда добавляем новую запись с даты "30.01.2017", то ищем, есть ли запись в БД с этими реквизитами и с границами С<=30.01.2017 По>30.01.2017. Если такая запись нашлась, то запоминаем у нее Олд_По=По, меняем в ней По на 30.01.2017 и создаем новую запись С 30.01.2017 По = Олд_По (разумеется все это в транзакции). В такой табличке найти срез на нужную дату - это select ... where "С"<=q_date and "По">q_date and (остальные условия) Ну и для хранения остатков - Добавляем два ресурса "Оборот" и "Остаток" и когда добавляем новую запись, то берем Остаток предыдущей записи, прибавляем к нему добавляемый Оборот и записываем новый Остаток сразу же в таблицу. Была еще пара любопытных тонкостей по записи Задним числом, но точно я не помню. |
|||
40
Волшебник
модератор
30.01.17
✎
12:30
|
(38) Имя файла базы указывается вторым параметром
SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version). |
|||
41
Волшебник
модератор
30.01.17
✎
12:31
|
(39) Это всё не нужно. Остаток = общий оборот. Хранить надо только обороты, возможно свёрнутые за период. Самый свёрнутый оборот и есть остаток
|
|||
42
Волшебник
модератор
31.01.17
✎
18:03
|
Регистр заработал. Идея в (19) сработала, только понадобилась тонкая настройка дат
Date TOTALS_BOUNDARY1; if (fromDate.getTime() == app.beginOfMonth(fromDate).getTime()) { TOTALS_BOUNDARY1 = app.beginOfMonth(fromDate); } else { TOTALS_BOUNDARY1 = app.beginOfNextMonth(fromDate); } Date TOTALS_BOUNDARY2; if (toDate.getTime() == app.endOfMonth(toDate).getTime()) { TOTALS_BOUNDARY2 = app.endOfMonth(toDate); } else { TOTALS_BOUNDARY2 = app.endOfPreviousMonth(toDate); } |
|||
43
Torquader
31.01.17
✎
18:50
|
Понятно, что нужно хранить свёрнутые итоги за периоды, так как это ускорит выполнение запроса. Но, итоги за периоды нужно собирать не по датам, а по количеству записей, например, если в каком-то периоде записей нет, то какой смсл в хранении итогов по нему, а если есть период, где в каждый момент времени много записей, то придётся делать более подробную детализацию итогов.
Ну и, конечно, где-то нужно хранить итог на конец, чтобы можно было быстро его показать - людей часто интересует общий итог, а не итог на какое-то конкретное время. |
|||
44
Волшебник
модератор
31.01.17
✎
19:52
|
(43) Общий итог на конец хранится в регистре оборотов без измерения "Месяц"
|
|||
45
Злопчинский
31.01.17
✎
22:30
|
..в итоге внезапно получили идеологию хранения регистров одноэсовскую
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |