Python to help the VET engineer

Hi all.
In this article I will provide some Python scripts for solving issues that a construction organization’s technical assistance engineer sometimes encounters. I riveted it myself based on information from the internet. Pros will be bored), level “without a programmer’s diploma”.

The work laptop uses: Win10, Python 3.11, Office2019. I’ll program it in PyScripter (I like it))

Example 1. It is necessary to archive (not in the sense of packing)

Tests are being carried out on individual sections of the pipeline, 50-60 pieces. Each one has a folder. Since neither the customer, nor technical supervision, nor anyone else can decide how best to formalize this matter, a situation arises when a bunch of documents have 2-3-4 formatting options. This means you need a script that will put the current version into the archive folder. (Well, yes, “my computer” or “total commander” can’t cope with this at all)):

##------------ЗАДАЧА---------------------------
## Создать папку Архив, в ней создать подпапку
## Переместить все файлы ворд/Эксель в подпапку архива

import glob, os, shutil

source_dir = os.getcwd() #Path where your files are at the moment
dst = source_dir+'/Архив/Вар2' #Path you want to move your files to

if not os.path.isdir(dst):           #создаем архив
    os.makedirs(dst)

#либо выбираем типы файлов - типа оффис
format_move_files = ['*.xls*', '*.doc*']
#либо все.
##format_move_files = ['*.*']

for fmf in format_move_files:
    files = glob.iglob(os.path.join(source_dir, fmf))
    for file in files:
        if os.path.isfile(file):
            shutil.move(file, dst)

Example 2. Create folders

Somehow there were a lot of files in one folder. And then the adversaries again came up with their wishes – each file in its own folder. Well, okay. It’s better to lose a day…then it will happen on its own in a minute. The idea is this: I get a list of files in the same total, I save it in the “folders.txt” file. Now his script should open and stamp the folders:

import os

codirovk = 'utf-8'

#------------вар2 работает------------------
with open('папки.txt', "r", encoding=codirovk) as file1:
    # итерация по строкам
    for line in file1:
        print(line.strip())
        if not os.path.isdir(line.strip()): ##делаем папки если их нет
            os.makedirs(line.strip())


#------------вар1 работает------------------
##file1 = open('папки.txt', "r")
##
### считываем все строки
##lines = file1.readlines()
##
### итерация по строкам
##for line in lines:
####    print(line.strip())
##    if not os.path.isdir(line.strip()): делаем папки если их нет
##        os.makedirs(line.strip())
##
### закрываем файл
##file1.close

Example 3. Retrieving files

And then they somehow send a folder with estimates, and they have each file in a separate folder, and mixed with all sorts of statements, and even the names of the files are dancing, well, there are 392 of them. What to do, what to do – uncover the python. You need to get all the estimate files and simultaneously rename them into one folder:

# задача - достать из множества папок все файлы в одну папку (где скрипт)
# допзадача - переименовать добавляя имена подпапок

import os, shutil
import glob
import re

dst = os.getcwd()
print(dst)

# допзадача переименовать добавляя имена подпапок
for name in sorted(glob.glob(dst+'/**/*локал*.xls', recursive=True)):
# имеем D:\1 На почту\КС-6\Глава 1\01-02-01Р-01\Л0326174_Локальная смета.xls
# вырезаем эту часть D:\1 На почту\КС-6\   и заменяем косые черты на тире
    newname = name[len(dst)+1:]
    newname = re.sub(r'\\', '-', newname)
    os.rename(name, newname)

# пройтись по всем папкам каталога запуска скрипта и переместить
# файлы *локал*.xls в папку скрипта
for name in sorted(glob.glob(dst+'/**/*локал*.xls', recursive=True)):
    try:
        shutil.move(name, dst)
    except:
        pass

Example 4. From Word to PDF)

There are a couple of dozen Word files in docx format, you need a pdf of them. Well, of course, I’ll sit with each handle to open it and save it as. Although there are also PDF printers…..Okay, let’s go with Python:

##*******************работает только docx

#pip install docx2pdf

from docx2pdf import convert  
import os

convert(os.getcwd()) # конвертация текущего каталога

Example 5 with subexample 6. Working with Excel. Replacing text in multiple files.

We built and built and finally built it. But …. yes, your division: why, when 85% of the executive documentation has already been done and signed (and this is approximately 1200-1500 acts of hidden work done in Excel) suddenly some kind of infection comes up with the idea to change the signatory because of games general contractor-subcontractor-subsubcontractor. And, sho, these people think, joyfully rubbing their hands, that I will suffer. Well, hold on – where is my boa constrictor, it’s time to strangle that one…. Oh well, let’s see what’s on the Internet for python. And there are a lot of things there, the ones that caught my eye are:

  • openpyxl – only works with xlsx To use it, a subtask arose to convert from xls to xlsx. Let’s look at the question on the Internet. We find pyexcel, xls2xlsx – but they ruin the formatting. Find pywin32. We do:

# Задача: конвертация эксель из xls в xlsx
# Все остальные библиотеки работают вкось
# Эксель должен быть установлен на компе!!!

# pip bloks
##     python -m pip install --upgrade pywin32

# import bloks
import os

import win32com.client as win32

# config bloks
path =os.getcwd()
format_files = ('.xls')

pred_prefiks_file_name=""

# relise bloks
for root, dirs, files in os.walk(path):
    for file in files:
        if(file.endswith(format_files, 0, len(file))):
##            print(os.path.join(file))## - этот вариант выводит только имя файла
            print(file)
##        print(os.path.join(root, file))## - этот вариант выводит полный путь и имя файла
            # -------делаем через COM объект -----------------------------
            excel = win32.gencache.EnsureDispatch('Excel.Application')
            wb = excel.Workbooks.Open(os.path.join(root, file))
            wb.SaveAs(pred_prefiks_file_name+os.path.join(root, file)+'x', FileFormat = 51)    #FileFormat = 51 is for .xlsx extension
            wb.Close()                               #FileFormat = 56 is for .xls extension
            excel.Application.Quit()

input("Работа завершена. Тисни ентер.")

Next we process openpyxl, but it also breaks the formatting. We search further and find:

It practically works as it should. I make a script through it, and delete the extra sheet using pywin32.

## худо бедно работает как надо мне, но компонент платный

##pip install aspose-cells
##pip install aspose-cells-python
##python -m pip install --upgrade pywin32

import os
from aspose.cells import Workbook, ReplaceOptions
import win32com.client as win32

path =os.getcwd()
format_files = ('.xlsx')##'.pdf','.doc', '.docx', '.dwg', '.py' ## - закомментировать если нужны все файлы

find_str="Руководитель проекта ООО "Капуста" "
removent_str="Заместитель генерального директора по объектам ООО "Рога и копыта""

# ВНИМАНИЕ - замена осуществляет по полным данным в ячейке. Т.е. меняется ячейка на ячейку

pred_prefiks_file_name=""

for root, dirs, files in os.walk(path):
    for file in files:
        if(file.endswith(format_files, 0, len(file))):## - закомментировать если нужны все файлы
            print(file)
            # Load Excel file
            workbook = Workbook(file)   ##Workbook("Workbook.xlsx")
            # Create replace options
            replace = ReplaceOptions()
            # Set case sensitivity and text matching options - раздел выдает ошибку
##            replace.setCaseSensitive(False)
##            replace.setMatchEntireCellContents(False)
            # Replace text
            workbook.replace(find_str, removent_str, replace)
            # Save as Excel XLSX file
            workbook.save(pred_prefiks_file_name+file);

## этот блок удаляет последний добавляемый лист 'Evaluation Warning' - по факту просто последний
            excel = win32.gencache.EnsureDispatch('Excel.Application')
            wb = excel.Workbooks.Open(os.path.join(root, pred_prefiks_file_name+file))
            ws = wb.ActiveSheet
            try:
                excel.DisplayAlerts=False
                wb.Worksheets(wb.Sheets.Count).Delete()
            finally:
                pass
            wb.Save()
            wb.Close()
            excel.Application.Quit()

input("Работа завершена. Тисни ентер.")

Yeah, I’m missing something. It’s all kind of clumsy. Stop, no one can do this job better than Excel, which means the same solution – pywin32. And there was no need to convert anything. We look for materials on the Internet, look through them, try 50 times with improvement along the way, ready:

##python -m pip install --upgrade pywin32

import os
import win32com.client as win32
import re

path = os.getcwd()
format_files = ('.xlsx', '.xls')##'.pdf','.doc', '.docx', '.dwg', '.py' ## - закомментировать если что-то не надо

# ищем строку
find_str="Сидоров Ю.М."
# строка для замены найденной строки
removent_str="Сидоров Ю.А."

# делаем 4 замены по порядку, а можно было и через список сделать

#Сидоров Ю.М.                                     Сидоров Ю.А.
#Руководитель проекта ООО "Капуста"               Заместитель генерального директора по объектам ООО "Рога и копыта"
#Сидоров Ю.М. Приказ №15 29.03.2023               Сидоров Ю.А. Приказ № П100  от  31.09.2022
#Иванов А.А.                                      Сидоров Ю.А.

#количество строк в которых надо делать поиск
row_find = 125
#количество столбцов в которых надо делать поиск
col_find = 40

#если надо спереди имени файла добавить префикс
pred_prefiks_file_name=""

excel = win32.gencache.EnsureDispatch('Excel.Application')

for root, dirs, files in os.walk(path):
    for file in files:
        if ((file.endswith(format_files, 0, len(file))) and (not file.endswith('~$', 0, 2))):
            # not file.endswith('~$', 0, 2) - защита от временных файлов эксель которые имена начинаются на ~$
            print('файл: ',file)
            #print(os.path.join(file))## - этот вариант выводит только имя файла
            #print(os.path.join(root, file))## - этот вариант выводит полный путь и имя файла
##            excel = win32.gencache.EnsureDispatch('Excel.Application')
            wb = excel.Workbooks.Open(os.path.join(root, file))
            print('листов: ', wb.Worksheets.Count)
            for sh_i in range(1, wb.Worksheets.Count+1):  #перебираем листы книги
                ws = wb.Worksheets(sh_i)    # идем на лист и активируем его
                ws.Activate()
                print('лист: ', sh_i)
                fp = 0
                cii2 = 0
                for row_i in range(1, row_find): #ws.Columns.Count - это вообще все строки
                    for col_i in range(1, col_find): #ws.Rows.Count - это вообще все колонки
                        if ws.Cells(row_i,col_i).Value:
                            cii2 = cii2 + 1
                            #вариант с re - заменяет внутри
                            data_from_cell = str(ws.Cells(row_i,col_i).Value) #получаем строку из данных
                            result = re.findall(find_str, data_from_cell)
                            if len(result) > 0:
                                print('в ячейке: ',row_i,',',col_i)
                                print('данные в ячейке: '+data_from_cell)
                                fp = 1
                                data_from_cell2 = re.sub(find_str, removent_str, data_from_cell, count=0)
                                print('измененные данные: '+data_from_cell2)
                                ws.Cells(row_i,col_i).Value = data_from_cell2
                                print('замена выполнена')

                            #вариант через данные эксель - совпадение по ячейке полностью - плохой вариант
    ##                        if ws.Cells(row_i,col_i).Value == find_str:
    ##                            print('найдено на листе: ', sh_i)
    ##                            print('в ячейке: ',row_i,', ',col_i)
    ##                            fp = 1
    ##                            ws.Cells(109,1).Value = removent_str
    ##                            print('замена выполнена')

                if fp == 0:
                    print('не найдено на листе: ', sh_i)
                print('пройдено ячеек: ', cii2)
            wb.Save(os.path.join(root, pred_prefiks_file_name+file))
            wb.Close()
##            excel.Application.Quit()

excel.Application.Quit()

print('')
print('----------------------------------------------')
input("Работа завершена. Тисни ентер.")

In general, I didn’t find how to do search/replace using pywin32. I go through the given area cell by cell. At first I replaced the entire cell – but you can’t replace individual text inside a cell, just the whole thing. Then, through the re module, it began to work as I wanted. It works slower than aspose, but somehow it’s calmer for me)).

p.s. That’s how we live in a vocational school))

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *