Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

17 Февраль 2020, 06:42 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Вы можете задать вопрос по LibreOffice или Apache OpenOffice без регистрации, используя форму
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1   Вниз
  Печать  
Автор Тема: Скрипт на Python запускает Libre calc и запускает макрос  (Прочитано 673 раз)
0 Пользователей и 1 Гость смотрят эту тему.
georgiy123
Участник
**
Offline Offline

Сообщений: 20


« Стартовое сообщение: 17 Январь 2020, 10:10 »

Ребята , всем привет ! , спасибо вашему форуму , и всем кто помогал мне дописать этот скрипт
Каждый день обрабатываю логи , в архиве +100 тхт файлов
Скрипт работает по файловой системе (удаляет , сохраняет , объединяет, открывает    , делает всё для результата )
Макрос ( module 1 ) каждый файл тхт всталяет как отдельный лист (страницу ) и на каждом листе делает Условное форматирование в столбце F
Макрос2 ( module 2 ) точно также вставляет файл из папки , ну только 1 , и удаляет строки по условию где сработало условное форматирование
Python
Код:
import os
import time
import tarfile
import sys
import subprocess
from pathlib import Path
import fileinput
import glob
#time.sleep(время в секундах ) пауза на несколько секунд
print('Скрипт начал начал работу , ждите окончание ')
path='C:\\Users\\g.nerovniy\\Desktop\\log1' #путь откуда берется ахрив .tar
path2='C:\\Users\\g.nerovniy\\Desktop\\log' #путь где будет происходить работа с файлами ( распаковка , удаление ,обьеденение )
print('Удаление ненужный файлов ')
directory='C:\\Users\\g.nerovniy\\Desktop\\log\\'# удаляются все файлы в папке
os.chdir(directory)
files=glob.glob('*.txt')#
for filename in files:#
    os.unlink(filename)#
time.sleep(5) #
print("Готово! ")#
print("Копирование файлов , распаковка файлов ")#
for file_name in os.listdir(path):# распаковка архива с path в path2
base_name, ext = os.path.splitext(file_name)#
abs_file_name = os.path.join(path, file_name)#
tar = tarfile.open(abs_file_name, 'r' )#
tar.extractall(path2)#
name_file_ok = file_name[:-7]# срезаное имя файла , если 2020-01-01.tar.gz  то 2020-01-01
time.sleep(3)#
print('Распаковка и копирование завершено!')
print('Запуск LibreOffice')
time.sleep(3)
command = ("C:/Program Files/LibreOffice/program/scalc.exe -norestore " )# запуск либр офис
p = subprocess.Popen(command)
print("Запуск макроса ")
time.sleep(5)
command = ("C:/Program Files/LibreOffice/program/scalc.exe   macro:///standard.module1.main" )# запуск макроса
p = subprocess.Popen(command)
time.sleep(15)#
command = ("C:/Program Files/LibreOffice/program/scalc.exe macro:///standard.module1.delle" )# запуск второго макроса
p = subprocess.Popen(command)
print("Обьеденение файлов")    
time.sleep(1) #
file_list = glob.glob("C:\\Users\\g.nerovniy\\Desktop\\log\\*.txt")#объеденение всех тхт файлов в один
with open('C:\\Users\\g.nerovniy\\Desktop\\log\\mismatching.txt', 'w') as file:#
    input_lines = fileinput.input(file_list)#
    file.writelines(input_lines)#
print("Обьеденение завершено ")
time.sleep(1) #
print('Удаление ненужный файлов ')#удаление всех файлов в папке начинаюищхся на 0
directory='C:\\Users\\g.nerovniy\\Desktop\\log\\'#
os.chdir(directory)#
files=glob.glob('0*.*')#
for filename in files:#
    os.unlink(filename)#
time.sleep(1) #
print("Удаление завершено ")
print("Запуск LibreOffice ")
command = ("C:/Program Files/LibreOffice/program/scalc.exe -norestore " )#запуск либр офис
p = subprocess.Popen(command)
print("Запуск макроса")
time.sleep(3)
command = ("C:/Program Files/LibreOffice/program/scalc.exe   macro:///standard.module2.main" )# запуск макроса их сторого модуля
p = subprocess.Popen(command)
time.sleep(15)#
command = ("C:/Program Files/LibreOffice/program/scalc.exe macro:///standard.module2.delsave" )#зупуск второго макроса
p = subprocess.Popen(command)
time.sleep(25)#
print("Готово! ")
print("Перемещение файлов по папкам")
okpath=name_file_ok+'.ods'# было 2020-01-01 стало 2020-01-01.ods
for path in Path('C:\\Users\\g.nerovniy\\Desktop\\').glob('Logi.ods'):# перенос файлов с рабочего стола , по папкам
    path.replace(Path('C:\\Users\\g.nerovniy\\Desktop\\') / okpath)#
time.sleep(1)
for path in Path('C:\\Users\\g.nerovniy\\Desktop\\').glob('mis.ods')#:
    path.replace(Path('C:\\Users\\g.nerovniy\\Desktop\\Mismatching\\') / okpath)#
print('Перемещение завершено!')

Libre calc Basic (если не ошибаюсь )

Module 1
Код:
private sub main
    dim p$, f$, t$, rw&, cl&, a(), i&
    dim wb as object, ws as object, c as object
    
    p="C:\Users\g.nerovniy\Desktop\log\" 'путь откуда брать тхт файлы
    f=dir(p+"*.txt")
    if len(f) then wb=thiscomponent else exit sub
    
    do          
       wb.sheets.insertnewbyname(f,i)
       ws=wb.sheets(i):i=i+1:rw=0
       open p+f for input as #1
            do while not eof(#1)
               line input #1, t
               a=split(t)
               for cl=0 to ubound(a)
                   c=ws.getcellbyposition(cl,rw)
                   select case cl
                       case 0 to 2, 5 to 7
                          c.setvalue(a(cl))
                       case else
                          c.setstring(a(cl))
                   end select
               next
               rw=rw+1
            loop
       close #1
       setFormat ws, rw
       f=dir
    loop while len(f)
    oDoc = ThisComponent

oDoc.Sheets.removeByName("Лист1")
end sub
 
sub setFormat(ws as object, rw&)
    dim r as object, cf as object
 
    r=ws.getcellrangebyname("f1:f"+rw)
    cf=r.conditionalformat  
    
    condFormat "0.95", "" , "Good", 3, cf
    condFormat "0.9", "0.95", "Neutral", 7, cf
    condFormat "0.85", "0.8999", "Bad", 7, cf
    condFormat "0", "0.85", "Error", 7, cf
    
    r.conditionalformat=cf
    
End Sub
 
sub condFormat(formula1$, formula2$, style$, o&, cf as object)
    dim p(3) As new com.sun.star.beans.PropertyValue
    
    
    
    
    p(0).name="StyleName"
    p(0).value=style
    p(1).name="Operator"
    p(1).value=o
    p(2).name="Formula1"
    p(2).value=formula1
    if len(formula2) then
       p(3).name="Formula2"
       p(3).value=formula2
    end if      
    cf.addnew(p)
   ' Application.Wait Time:=Now + TimeValue("0:00:02")
'delle
end sub

sub delle
odoc=thiscomponent
oSheet = oDoc.CurrentController.getActiveSheet()
myrows=oSheet.getrows
Dim args(0) As New com.sun.star.beans.PropertyValue
oDoc.storeToURL("file:///C:/Users/g.nerovniy/Desktop/Logi.ods", args())
oDoc.close(true)
end sub






Module 2

Код:
private sub main
    dim p$, f$, t$, rw&, cl&, a(), i&
    dim wb as object, ws as object, c as object
    
    p="C:\Users\g.nerovniy\Desktop\log\"
    f=dir(p+"*.txt")
    if len(f) then wb=thiscomponent else exit sub
    
    do          
       wb.sheets.insertnewbyname(f,i)
       ws=wb.sheets(i):i=i+1:rw=0
       open p+f for input as #1
            do while not eof(#1)
               line input #1, t
               a=split(t)
               for cl=0 to ubound(a)
                   c=ws.getcellbyposition(cl,rw)
                   select case cl
                       case 0 to 2, 5 to 7
                          c.setvalue(a(cl))
                       case else
                          c.setstring(a(cl))
                   end select
               next
               rw=rw+1
            loop
       close #1
       setFormat ws, rw
       f=dir
    loop while len(f)
    oDoc = ThisComponent

oDoc.Sheets.removeByName("Лист1")
end sub
 
sub setFormat(ws as object, rw&)
    dim r as object, cf as object
 
    r=ws.getcellrangebyname("f1:f"+rw)
    cf=r.conditionalformat  
    
    condFormat "0.95", "" , "Good", 3, cf
    condFormat "0.9", "0.95", "Neutral", 7, cf
    condFormat "0.85", "0.8999", "Bad", 7, cf
    condFormat "0", "0.85", "Error", 7, cf
    
    r.conditionalformat=cf
    
End Sub
 
sub condFormat(formula1$, formula2$, style$, o&, cf as object)
    dim p(3) As new com.sun.star.beans.PropertyValue
    p(0).name="StyleName"
    p(0).value=style
    p(1).name="Operator"
    p(1).value=o
    p(2).name="Formula1"
    p(2).value=formula1
    if len(formula2) then
       p(3).name="Formula2"
       p(3).value=formula2
    end if      
    cf.addnew(p)


end sub


sub delsave
 odoc=thiscomponent
 oSheet = oDoc.CurrentController.getActiveSheet()
 myrows=oSheet.getrows
 
 rowmax=3000
 rowmin=0
 
 For i=rowmax To rowmin step -1
 textnd = osheet.getcellbyposition(5,i).string
    If textnd >="0,95" Then
      myrows.removebyindex(i,1)
    End if  
 Next i
Dim args(0) As New com.sun.star.beans.PropertyValue
oDoc.storeToURL("file:///C:/Users/g.nerovniy/Desktop/mis.ods", args())
oDoc.close(true)
end sub



Если есть предложение как улучшить код , пишите ,буду рад  Смеющийся
« Последнее редактирование: 17 Январь 2020, 10:13 от georgiy123 » Записан
Bigor
Опытный пользователь
***
Offline Offline

Пол: Мужской
Сообщений: 841


« Ответ #1: 17 Январь 2020, 10:36 »

Я думаю простыню на питоне можно было бы в 15 строчек cmd файла вместить Улыбка Раз уже все равно под винду.
Записан
economist
Форумчанин
***
Offline Offline

Сообщений: 1 126


« Ответ #2: 17 Январь 2020, 11:23 »

Это всего 10-12 понятных строк на Python + Pandas + Numpy и в 10x раз более быстрая работа самого скрипта. Думаю короче с сохранением понятности - сделать уже невозможно.

Но оптимизация как цель - зло. В приведенном коде много полезных кусков, да и с методической т. зр. хорошо.

 
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
mikekaganski
Мастер
*****
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 1 701


« Ответ #3: 17 Январь 2020, 11:59 »

Охохо... Что оно делает-то? логи какого вида приводит к какому виду? удаляет оттуда что?
Записан

С уважением,
Михаил Каганский
economist
Форумчанин
***
Offline Offline

Сообщений: 1 126


« Ответ #4: 17 Январь 2020, 13:00 »

Это задача классификации типа до 0.8 - уд., 0.8-0.9 - хор., 0.9-1 - отл. В Pandas, например делается одной строкой:
Код:
df.результат = pd.cut(df.хиты, bins=[0.8, 0.9, 1.0], labels=['уд.', 'хор.', 'отл.'])

А считать 100 логов в один файл - еще пара строк
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
mikekaganski
Мастер
*****
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 1 701


« Ответ #5: 17 Январь 2020, 13:11 »

Так в том-то и беда. Решение любой задачи начинается с формализации: есть такой вход, нужен такой выход. Исходя из этого подбираются инструменты, пишется решение... А здесь - с первого сообщения решение без задачи. И хотя там вправду есть некоторые полезные элементы - типа "вот так можно устанавливать условное форматирование" - в целом это просто ужасающий костыльный монстр, начиная от выбора ЛО для задачи фильтрации "логов", и продолжая использованием макросов BASIC, вызываемых с помощью вызова ЛО из Python, вместо использования UNO в Python.
Записан

С уважением,
Михаил Каганский
economist
Форумчанин
***
Offline Offline

Сообщений: 1 126


« Ответ #6: 17 Январь 2020, 14:25 »

Имхо, из 100% случаев, когда очень нужна автоматизация, 
- 30% используют код-"лапшу" как в топике, написанную самим коряво, с кучей копипаста и макрорекордера
- 10% используют код, написанный программистами, грамотно и по ТЗ 
- 60% - не используют ничего и делают всё вручную. При это они оправдываются так
   - "не хочу быть как 30%"
   - "нет денег/гениев сделать как в 10%".

И вот эти 60% - и есть самое ужасное. Тут и оверхед с оверкиллом, и низкая производительность труда, субботы на работе, недосып и геморрой. Поэтому, на мой взгляд, нужно поощрять любые опыты в программировании, поскольку даже 30% прироста автоматизации - это много.

Макросы MSO/OO/LO, Python и SQL - пожалуй, наиболее подходящие платформы для самоучек и любительского прикладного программирования. В этом нет ничего необычного - куча великих художников, музыкантов, инженеров, web-дизайнеров и программистов были самоучками, а учиться начали уже став успешными.
Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
mikekaganski
Мастер
*****
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 1 701


« Ответ #7: 17 Январь 2020, 14:35 »

Это вопрос к постановке задачи. К умению задавать правильные вопросы. Когда человека в школе учат, что надо подходить к решению задачи последовательно. Когда рассказывают, что задавать вопрос типа "как мне достать условное форматирование из питона" - совершенно неверно, если сначала не объяснена общая задача, и следовательно, может быть, что для решения этой задачи обращаться к условному форматированию из питона вообще не надо, и такие некорректные вопросы приводят к тому, что знающие люди просто не способны направить новичка на правильный метод решения основной задачи. А уже из отсутствия этого в школе лезут костыли.
Записан

С уважением,
Михаил Каганский
Rafik
Форумчанин
***
Offline Offline

Сообщений: 104


« Ответ #8: 17 Январь 2020, 14:38 »

На мой взгляд, не проще ли грамотно загрузить данные в sqlite и оттуда, с помощью запроса получать данные для отчёта? Готовый отчёт можно сформировать в хоть в pdf, хоть в xls, хоть в csv и т.д. Не нужна будет куча геморроя с макросами.

Насчёт использования uno в питоне. У меня как-то под вендой ХР с питоном 3.4 и либре 5.1.1.2 не получилось сдружить питон с либре через uno. Шло зависание питона на строке с импортом uno. Никакого выхлопа на консоле: cmd + python.exe myScript.py. Принт перед импортом выдавал сообщение на консольку, а второй принт, сразу после строки с импортом, не отрабатывал.
После этого косо смотрю на uno.
Записан
mikekaganski
Мастер
*****
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 1 701


« Ответ #9: 17 Январь 2020, 14:43 »

Насчёт использования uno в питоне. У меня как-то под вендой ХР с питоном 3.4 и либре 5.1.1.2 не получилось сдружить питон с либре через uno. Шло зависание питона на строке с импортом uno. Никакого выхлопа на консоле: cmd + python.exe myScript.py. Принт перед импортом выдавал сообщение на консольку, а второй принт, сразу после строки с импортом, не отрабатывал.
После этого косо смотрю на uno.

Нууууу..... Улыбка

У меня как-то винда (ЛО, Эксель, .... подставить по вкусу) упала при работе с документом. С тех пор косо смотрю на <backreference>.
Записан

С уважением,
Михаил Каганский
Bigor
Опытный пользователь
***
Offline Offline

Пол: Мужской
Сообщений: 841


« Ответ #10: 17 Январь 2020, 14:48 »

Ну мы так и не знаем, что georgiy123 нужно было Улыбка Помимо выборки значений там еще и раскраска. Вдруг это самое важное во все проекте.
А что метод выбран странный, так зато практика и в питоне и бейсике Улыбка
« Последнее редактирование: 17 Январь 2020, 14:50 от Bigor » Записан
georgiy123
Участник
**
Offline Offline

Сообщений: 20


« Ответ #11: 22 Январь 2020, 08:18 »

не обисуйте строго )
я в этом новичок , слепил скрипт , всё работает , всё хорошо .
Прочитал ваши комментарии , кто-то говорит что всё очень плохо, ну приведите пример ? как надо , что надо ?
« Последнее редактирование: 22 Январь 2020, 14:49 от georgiy123 » Записан
economist
Форумчанин
***
Offline Offline

Сообщений: 1 126


« Ответ #12: 22 Январь 2020, 09:24 »

georgiy123, работает - и ладно! Но "код-лапша" и вызов одного из другого ради третьего - это не гуд.

Мир программирования прекрасен в том числе и от того, что в нем есть место хорошо читаемому коду (код пишется 1 раз, а читается 10-15). Его по-идее нужно писать так же тщательно, как писатель пишет рассказ.

Язык Питон очень выразителен и идеально подходит для красивых программ. И красивые программы в разы легче "чинятся" (причем не только автором), если что-то сломалось (а сломается обязательно, подождите пару месяцев).

Вы справились с задачей, но все-же допустили ошибку - не выбрали оптимальный инструмент. Задачи, подобные вашей, давно решены на stackoverflow.com (SO), русскоязычных script-coding.com, forum.ru-board.com итд - "в одну строку", консольными утилитами (awk/grep/BAT/VBS итп). Но их время, имхо, ушло (читаемость кода там ужасная, если не нашел точно свой случай - не взлетит, документация трудна).

Теперь в анализе данных (и логов) рулит Python, но не сам по себе, а с NumPy и Pandas. Тут и краткий ясный код, читаемость, огромнейшее коммьюнити (язык 5 лет в Top-3) и куча готовых рецептов на SO (это не документация, а реальные кейсы). Плюс питон-хайп и... реально можно написать все самому из стыренных чужих кусов в 1-2 строки. Но получится уже не "лапша", а нечто компактное. Ваша задача реально решается за 10 строк на Python. И любая последующая (например, построить графики) - решится за 5-10 строк. Советую учить Pandas и продолжать расти. Хайп питона затянулся, эти знания не "протухнут", как некоторые другие, типа командной строки Windows и CMD.
« Последнее редактирование: 22 Январь 2020, 09:27 от economist » Записан

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...
Страниц: 1   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!