Скрипт на Python запускает Libre calc и запускает макрос

Автор georgiy123, 17 января 2020, 10:10

0 Пользователи и 1 гость просматривают эту тему.

georgiy123

Ребята , всем привет ! , спасибо вашему форуму , и всем кто помогал мне дописать этот скрипт
Каждый день обрабатываю логи , в архиве +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




Если есть предложение как улучшить код , пишите ,буду рад  ;D

Bigor

Я думаю простыню на питоне можно было бы в 15 строчек cmd файла вместить :) Раз уже все равно под винду.
Поддержать разработчиков LibreOffice можно можно тут, а наш форум вот тут

economist

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

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

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

mikekaganski

Охохо... Что оно делает-то? логи какого вида приводит к какому виду? удаляет оттуда что?
С уважением,
Михаил Каганский

economist

Это задача классификации типа до 0.8 - уд., 0.8-0.9 - хор., 0.9-1 - отл. В Pandas, например делается одной строкой:

df.результат = pd.cut(df.хиты, bins=[0.8, 0.9, 1.0], labels=['уд.', 'хор.', 'отл.'])


А считать 100 логов в один файл - еще пара строк
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

mikekaganski

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

economist

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

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

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

mikekaganski

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

Rafik

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

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

mikekaganski

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

Нууууу..... :)

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

Bigor

#10
Ну мы так и не знаем, что georgiy123 нужно было :) Помимо выборки значений там еще и раскраска. Вдруг это самое важное во все проекте.
А что метод выбран странный, так зато практика и в питоне и бейсике :)
Поддержать разработчиков LibreOffice можно можно тут, а наш форум вот тут

georgiy123

#11
не обисуйте строго )
я в этом новичок , слепил скрипт , всё работает , всё хорошо .
Прочитал ваши комментарии , кто-то говорит что всё очень плохо, ну приведите пример ? как надо , что надо ?

economist

#12
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.
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...