Форум программистов, компьютерный форум, киберфорум
Наши страницы
Java: Базы данных
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
Tester64
396 / 357 / 46
Регистрация: 22.05.2013
Сообщений: 2,518
#1

Аналог 1С

08.08.2014, 20:51. Просмотров 1156. Ответов 4
Метки нет (Все метки)

Помогите новичку!

Надо написать не сложную программу для оффлайн хранения простых справочников и документов. И возможно простые отчеты по документам (в текст или html)... Без учета остатков, реестров, накоплений - просто факт записи (и табличной части)... На 1С(7.7) набросал бы подобное за час-полтора... Но хотелось бы сделать программу бесплатной (для скачивания с сайта).
Есть ли в яве инструменты для подобного? Фреймворки? Движки? Конструкторы?

Как базу в иделе бы использовать DBF или SQLite...

...подумал что должно быть. Учитывая сколько лет яве и что она используется в банковской и учетной сфере...
Понятно что логика будет на яве(а не 1С), но плодить документы/справочники с нуля, придумывать логику контроля зависимости полей не охота... Списки и формы документов... Ведь если бухгалтерия некого (иностранного) завода захочет еще одну таблицу справочника завести или документов с отдельным журналом, вряд-ли программисты будут копировать логику со старых документов, пререопределять десятки-сотни полей(включая стандартные), придумывать таблицы хранения, привязку к старым документам и справочникам... Привязывать к инструментам пересчета полей при сбое...

если с нуля изобретать, понадобятся недели, если не месяцы на такую мелкую программку...

Насколько такую программу будет тяжело установить обычному пользователю? Самораспаковывающийся архив + "установите яву"? Инсталятор "все включено"?

1.5 года использую яву для андроида, надеялся что и перейти не тяжело будет. Да и при желании мультиплатформенной можно будет сделать...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.08.2014, 20:51
Ответы с готовыми решениями:

Аналог goToXY(x,y)
Подскажите, пожалуйста, аналог goToXY(x,y) из паскаля. Добавлено через 1 час...

Аналог DRKB
Существует ли "аналог" Delphi Russian Knowledge Base, но для Java?

Аналог ADOTable из c++ builder на java
Здравствуйте. Не подскажите, для java создан какой нибудь визуальный редактор...

Есть ли аналог такого в Java?
Здравствуйте! Скажите пожалуйста, как такую конструкцию оформить в Java? ...

Есть ли аналог struct (из C++) в Java ?
Есть ли аналог struct (из C++) в Java , без того чтоб создать новый класс ? ...

4
vTin
0 / 0 / 0
Регистрация: 07.08.2014
Сообщений: 4
08.08.2014, 22:02 #2
Я когда-то сталкивался с похожей задачей.
В одном из подразделений было нужно нечто для документов, но с элементами ERP системы.
Перед этим приглядывался к LibreOffice и его макросам и был в курсе, что можно писать для него на Java. В общем, с Java+LibreOffice получился неплохой вариант, но довольно сложный.
После некоторых дополнительных поисков, я остановился на Python+LibreOffice. Решение такое же красивое и удобное, но при этом более простое.
Советую попробовать с базой SQLite (независимо Java или Python).
Что касается обычного пользователя: установка LibreOffice и копипаста скриптов (или установочный скрипт для всего этого).
Одинаково хорошо работает как под Windows так и под GNU\Linux. Если заинтересует, могу бросить на почту python-скрипт.
0
magirus
Почетный модератор
Эксперт по компьютерным сетямЭксперт Windows
27947 / 15666 / 959
Регистрация: 15.09.2009
Сообщений: 67,839
Записей в блоге: 78
08.08.2014, 22:28 #3
Цитата Сообщение от vTin Посмотреть сообщение
могу бросить на почту python-скрипт.
можете разместить здесь, и тогда размеры благодарности (как минимум в моем лиТсе), не будут иметь размеров (в
пределах разумного)
0
Tester64
396 / 357 / 46
Регистрация: 22.05.2013
Сообщений: 2,518
08.08.2014, 22:52  [ТС] #4
Цитата Сообщение от vTin Посмотреть сообщение
могу бросить на почту python-скрипт
Кидайте! tester64@rambler.ru
Попробую...

если честно, расчитывал на более простой вариант... Было время - на делфи написал некое подобие справочников-документов (на SQLite) - список с фильтрами, быстрый поиск, редактирование через диалоги... Отдельный файл для структуры всех справочников с рускоязычными полями. Редактирование через диалоги со встроенными процедурами проверок, заполнения полей при открытии, записи полей при закрытии, кнопка отказ от записи... Почти дописал... немного тормозило и были недоисправленные глюки... Вроде "Парус" (конкурент 1С) написан похожим образом на Делфи... Легко добавляют новые документы и справочники...

Сейчас пытаюсь нечто подобное написать под андроид. Там даже чуть проще... Можно формы наследовать от "образца" (в делфи сложнее было). Но тут АПИ от Гугла (гадкое и ни с кем не совместимое).

Надеялся что подобное уже есть под яву с окошками! Мультиплатформенное. Ведь люди годами над подобным работали... даже вроде (еще не пробовал, но много читал) придумали NoSQL базы с документо-ориентированостью. И не одиночки вроде меня, а целые корпорации... Неужели никто до сих пор не придумал опенсорс аналога 1С на основе явы - нужен учет в справочниках с возможностью править юзерами - берется фрейворк и за 3-4 часа "накидываются" формочки и формируется в конструкторе база... Ведь на яве все банки работают... Неужели они все свою зарплату в 1С считают?

Помню я подобное за месяц на FoxPro создавал... Потом за ночь на 1С переписал(при нулевом знании 1С - по учебнику)... около 20 справочников было со сложной структурой.

Сейчас за полчаса "накидал" общую схему связанных справочников в 1С... Получилось около 6-7 справочников даже без документов. Но выложить бесплатную версию на сайт не могу - нужен "запускатель от 1С", а он стоит денег. И не малых (на каждый комп).

Добавлено через 8 минут
p.s. подобное встроено в большинство веб-движков. На друпале поблема не создать справочник, а красиво его вывести табличками и что-бы картинки не тормозили... А создание справочников (там они как-то по другому называются) там давно встроено. Вместе с дизайнером элементов... И необычными обработками реакций на PHP, если автору не нравятся стандартные...
0
vTin
0 / 0 / 0
Регистрация: 07.08.2014
Сообщений: 4
09.08.2014, 17:14 #5
можно конечно и здесь, хотя самолюбие требует для таких результатов статью в блоге

В наличии python скрипт для формирования нестандартного печатного документа штатного расписания и скрипт, который очень помог в разработке и упростил понимание python под LibreOffice (у LibreOffice свой собственный отдельный python, в последних версиях 3.3, и свои особенности запуска скриптов-макросов).
Проект выглядит так: в 1С храняться сведения (тут можно использовать SQLite), включаем шаблон LibreOffice, запускаем python-скрипт-макрос, PySide(Qt) диалог с параметрами, подтверждаем - получаем готовый отчет.
Ниже скрипт, который представляется как макрос в LibreOffice и формирует документ
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# -*- coding:utf-8 -*-
import sys
print(sys.path)
 
import os
import uno
from PySide import QtGui
from PySide import QtCore, QtUiTools
 
 
class ShtatScheduleFormater:
    ####### for   development ################
    @staticmethod
    def initXSC():
        if not 'XSCRIPTCONTEXT' in globals():
            from devDocInit import SScheduleXContext
            global XSCRIPTCONTEXT
            XSCRIPTCONTEXT = SScheduleXContext().XSCRIPTCONTEXT
    ##########################################
 
    V82 = None
 
    class ParametersDialog:
        def __init__(self, formater):
            self.app = QtGui.QApplication([''])
            file = QtCore.QFile(formater.localPath + formater.uiFilePath)
            file.open(QtCore.QFile.ReadOnly)
            self.widget = QtUiTools.QUiLoader().load(file)
            file.close()
            self.widget.DepComboBox.addItem('')
            self.widget.KategoryComboBox.addItem('')
            self.widget.FinancComboBox.addItem('')
            qDeps = 'SELECT DP.Наименование Name FROM Catalog.ПодразделенияОрганизаций DP WHERE DP.DeletionMark = false ORDER BY Name'
            depsQuery = formater.V82.NewObject("Query", qDeps)
            depsSels = depsQuery.Execute().Choose()
            while depsSels.next():
                self.widget.DepComboBox.addItem(depsSels.Name)
            qKats = 'SELECT KT.Наименование Name FROM Catalog.КатегорииДолжностейПерсонала KT WHERE KT.DeletionMark = false ORDER BY KT.Наименование'
            katsQuery = formater.V82.NewObject("Query", qKats)
            katsSels = katsQuery.Execute().Choose()
            while katsSels.next():
                self.widget.KategoryComboBox.addItem(katsSels.Name)
            qFins = 'SELECT FT.Наименование Name FROM Catalog.СтатьиФинансирования FT WHERE FT.DeletionMark = false ORDER BY FT.Наименование'
            finsQuery = formater.V82.NewObject("Query", qFins)
            finsSels = finsQuery.Execute().Choose()
            while finsSels.next():
                self.widget.FinancComboBox.addItem(finsSels.Name)
 
        def exec_(self):
            return self.widget.exec_()
 
    def getData(self):
        parmDialog = ShtatScheduleFormater.ParametersDialog(self)
        pDialWidget = parmDialog.widget
        if not pDialWidget.exec_():
            QtCore.QCoreApplication.exit()
            raise Exception('close dialog')
            sys.exit(0)
        PersonalYearFrame = self.doc.TextFrames.getByName('PersonalYearFrame')
        PersonalYearFrame.getText().insertString(PersonalYearFrame.getStart(),\
                           '%s \r\n %s'%(pDialWidget.KategoryComboBox.currentText(), pDialWidget.DepComboBox.currentText()), 0)
 
        FinanceTable = self.doc.TextTables.getByName('FinanceTable')
        FinanceTable.getCellByName('A1').String = pDialWidget.FinancComboBox.currentText()
 
        q = '''
            SELECT  ШР.ПодразделениеОрганизации.Наименование dep,
                    ШР.Должность.Наименование posit,
                    ШР.КоличествоСтавок cnt,
                    ШР.МесячнаяСтавка base,
                    ISNULL(НадбавкиПоШтату.Показатель, 0)/100 + 1 k,
                    "=<D{0}>*<E{0}>" sm,
                    "=<F{0}>*<C{0}>" ttlSm
              FROM РегистрСведений.ШтатноеРасписаниеОрганизаций.СрезПоследних КАК ШР
              LEFT OUTER JOIN (
                      SELECT  НадбавкиПоШтату.ПодразделениеОрганизации,
                              НадбавкиПоШтату.Должность,
                              СУММА(НадбавкиПоШтату.Показатель1) Показатель
                         FROM РегистрСведений.НадбавкиПоШтатномуРасписаниюОрганизаций.СрезПоследних КАК НадбавкиПоШтату
                        WHERE НадбавкиПоШтату.ВидНадбавки.Код = "00109"
                          GROUP BY
                              НадбавкиПоШтату.ПодразделениеОрганизации,
                              НадбавкиПоШтату.Должность
                      ) КАК НадбавкиПоШтату
                        ПО ШР.ПодразделениеОрганизации = НадбавкиПоШтату.ПодразделениеОрганизации
                            И НадбавкиПоШтату.Должность = ШР.Должность
                WHERE (ШР.ПодразделениеОрганизации.Наименование = "{1}" OR "{1}" = "")
                  AND (ШР.Должность.КатегорияПерсонала.Наименование = "{2}" OR "{2}" = "")
                  AND (ШР.СтатьяФинансированияФорма14.Наименование = "{3}" OR "{3}" = "")
                ORDER BY
                      ШР.ПодразделениеОрганизации.Наименование,
                      ШР.Должность.Наименование
            '''.format('{0}', pDialWidget.DepComboBox.currentText()
                            , pDialWidget.KategoryComboBox.currentText()
                            , pDialWidget.FinancComboBox.currentText() )
        query = self.V82.NewObject("Query", q)
        return query.Execute().Choose()
 
    def fetch(self):
        from com.sun.star.beans import PropertyValue
        mainTable = self.doc.TextTables.getByName('MainTable')
        sels = self.getData()
        controller = self.doc.getCurrentController()
        frame = self.doc.getCurrentController().Frame
        frame.activate()
        dispatcher = XSCRIPTCONTEXT.ctx.ServiceManager.createInstance('com.sun.star.frame.DispatchHelper')
 
        lastDep = None
        i = 1  # string number
        n_n = 0
        while sels.Next():
            if not sels.__getattr__('dep') == lastDep:
                if not lastDep is None:
                    mainTable.getRows().insertByIndex(i, 1)
                    i+=1
                    mainTable.getCellByName('%s%d'%(self.clmns['posit'],i)).String = 'ИТОГО'
                    mainTable.getCellByName('%s%d'%(self.clmns['ttlSm'],i)).Formula = \
                        '=sum(<{0}{1}:{0}{2}>)'.format(self.clmns['ttlSm'], i-n_n, i-1)
                    mainTable.getCellByName('%s%d'%(self.clmns['cnt'],i)).Formula = \
                        '=sum(<{0}{1}:{0}{2}>)'.format(self.clmns['cnt'], i-n_n, i-1)
                mainTable.getRows().insertByIndex(i, 1)
                i+=1
                lastDep = sels.__getattr__('dep')
                controller.select(mainTable.getCellRangeByName('%s%d:%s%d'%(self.fColumn,i,self.lColumn,i)))
                prop = (PropertyValue(),)
                dispatcher.executeDispatch(frame, ".uno:MergeCells", "", 0, ())
                prop[0].Name = 'Bold'
                prop[0].Value = True
                controller.select(mainTable.getCellByName('%s%d'%(self.fColumn,i)))
                dispatcher.executeDispatch(frame, ".uno:Bold", "", 0, prop)
                prop[0].Name = "CenterPara"
                prop[0].Value = True
                controller.select(mainTable.getCellByName('%s%d'%(self.fColumn,i)))
                dispatcher.executeDispatch(frame, ".uno:CenterPara", "", 0, prop)
                mainTable.getCellByName('%s%d'%(self.fColumn,i)).String = sels.__getattr__('dep')
                n_n = 0
            mainTable.getRows().insertByIndex(i, 1)
            i+=1;     n_n+=1
            for clm in self.clmns:
                if clm in ['sm','ttlSm']:
                    mainTable.getCellByName('%s%d'%(self.clmns[clm],i)).Formula = sels.__getattr__(clm).format(i)
                elif clm == 'num':
                    mainTable.getCellByName('%s%d'%(self.clmns[clm],i)).Value = n_n
                elif clm in ['cnt', 'base', 'k']:
                    mainTable.getCellByName('%s%d'%(self.clmns[clm],i)).Value = sels.__getattr__(clm)
                else:
                    mainTable.getCellByName('%s%d'%(self.clmns[clm],i)).String = sels.__getattr__(clm)
        i+=1
        mainTable.getCellByName('%s%d'%(self.clmns['posit'],i)).String = 'ИТОГО'
        mainTable.getCellByName('%s%d'%(self.clmns['ttlSm'],i)).Formula = \
            '=sum(<{0}{1}:{0}{2}>)'.format(self.clmns['ttlSm'], i-n_n, i-1)
        mainTable.getCellByName('%s%d'%(self.clmns['cnt'],i)).Formula = \
            '=sum(<{0}{1}:{0}{2}>)'.format(self.clmns['cnt'], i-n_n, i-1)
        del self.V82
 
    def __init__(self, *args):
        import win32com.client
        import pythoncom
        ShtatScheduleFormater.initXSC()
        pythoncom.CoInitialize()
        self.localPath       = 'C:\\Program Files (x86)\\LibreOffice 4\\share\\Scripts\\python\\shtatSchedule\\'
        self.uiFilePath      = 'ShtatSchedule.ui'
        self.V82_CONN_STRING = 'File="C:\\1cbackup\\BudgetHRM_copy";Ref=v8_db;'
        self.V82             = win32com.client.Dispatch("V82.COMConnector").Connect(self.V82_CONN_STRING)
        self.clmns           = {'num':'A', 'posit':'B', 'cnt':'C', 'base':'D', 'k':'E', 'sm':'F', 'ttlSm':'G'}
        self.fColumn         = 'A'
        self.lColumn         = 'G'
        self.doc             = XSCRIPTCONTEXT.getDocument()
        sys.path.append(self.localPath)
        try:
            self.fetch()
        except:
            del self.V82
 
def getShtatSchedule(*args):
    ShtatScheduleFormater(*args)
 
if __name__ == '__main__':
    getShtatSchedule()
Особенности:
* ShtatScheduleFormater - класс-менеджер для формирования отчета, но для запуска макроса обязательно нужен метод, подобный getShtatSchedule в корне модуля, иначе скрипт не запуститься
Python
1
2
def getShtatSchedule(*args):
    ShtatScheduleFormater(*args)
* LibreOffice python не включает в PATH директорию запущенного скрипта, т.к. отчет небольшой, я добавил путь в явном виде
Python
1
2
self.localPath       = 'C:\\Program Files (x86)\\LibreOffice 4\\share\\Scripts\\python\\shtatSchedule\\'
sys.path.append(self.localPath)
* fetch - метод сборки отчета (наименование запомнилось после ERP Axapta)
* getData - забирает данные из 1С
* ParametersDialog - класс qt-диалога с параметрами
* Очень важно для дебага и для интерактивной работы с python: метод initXSC
если вы запускаете отчет в режиме дебага, то переменной окружения XSCRIPTCONTEXT не существует, её нужно создавать или как-то выкручиваться без неё.
На этот случай был написан вот такой скрипт
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -*- coding:utf-8 -*-
import os
import sys
import uno
import socket
 
class XCont:
    def __init__(self, ctx, doc, inv):
        self.ctx = ctx;        self.doc = doc;        self.inv = inv
    def getDocument(self):        return self.doc
 
class SScheduleXContext( ):
    def __init__(self):
        ctx = uno.getComponentContext()
        resolver = ctx.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", ctx)
        smgr = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ServiceManager")
        desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
        doc = desktop.loadComponentFromURL('file:///c:/Program Files (x86)/LibreOffice 4/share/Scripts/python/shtatSchedule/ShtatSchedule.ott',"_blank", 0, () )
        self.XSCRIPTCONTEXT = XCont(ctx,doc,0)
Запускается LibreOffice на подключение в режиме дебага
Bash
1
soffice "-accept=socket,host=localhost,port=2002;urp;StarOffice.NamingService"
Далее в интерпретаторе запускается скрипт с вашим макросом, в данном случае вызывается метод getShtatSchedule()

Были и другие реализации похожих задач. Что касается стороны GNU - с неми проблем было меньше всего, сложнее как всегда с тайным и загадочным 1С.
В Вашем случае можно воспользоваться SQLite+Python+LibreOffice+Qt. Для ORM можно использовать sqlalchemy. Что касается такой фишки как Grid - тут немного сложнее, но как вариант делать так: список выводиться в сам LibreOffice Calc, а новые элементы, редактирование и удаление по дополнительным кнопкам на панельке. Повезёт, если найдёте готовый вариант визуального редактирования строк таблиц.
Важное замечание, как любителю Java: если будете использовать Python в первую очередь начните с интерактивного режима/дебага. Написали, пол проекта запустили, что-то выполнилось, следующие команды пишите "не отходя от кассы" - прямо внутри работающего приложения, пусть выполняет - вы сразу посмотрите на результат. Такой подход очень помогает при работе с LibreOffice, да и вообще с любыми задачами на python.
Ну и наконец GNU\Emacs Юзаю и Всем рекомендую Очень удобный редактор (+Evil mode)
0
09.08.2014, 17:14
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.08.2014, 17:14

Написать аналог Lombok с другими методами
Гуру, подскажите куда копать? (пишу на spring) Задача/задумал написать...

Аналог System.Collections.Generic.IEnumerable<out T>
Какой аналог есть в Java System.Collections.Generic.IEnumerable&lt;out T&gt; из C#?

Аналог PHP функции unpack в Java
Здравствуйте!Подскажите, пожалуйста ,есть ли в Java какой-либо аналог функции...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru