Как из двух идентичных программ сделать одну (Python 3.7, qt Frame)

требовалось создать программу для проведения abc и xyz анализа данных из Excel файла. Отдельно две программы написать получилось (кривовато, правда). А вот чтобы она была одна и по кнопке проводился бы и тот и другой одновременно - не получается. Код одной из них прилагаю

import sys
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QTableWidgetItem, QTableWidget, QHeaderView, QFrame
from openpyxl import load_workbook
import ABC
from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT


# Строка данных
class Record:
    # Число по порядку
    number: int

    # Поставщик
    supplier: str

    # Товар
    good: str

    # Потребность
    need: float

    # Цена товара
    price: float

    # Ожидаемая окупаемость
    income: float

    # Доля реализации по позиции
    prez: float

    # Доля реализации по позиции с возрастающим итогом
    prezbig: float

    # Группа
    group: str

    # Инициализатор
    def __init__(self, number, supplier, good, need, price, income):
        self.number = number
        self.supplier = supplier
        self.good = good
        self.need = need
        self.price = price
        self.income = income
        self.prez = -1
        self.prezbig = -1
        self.group = ''


# Главный класс приложения
class ExampleApp(QtWidgets.QMainWindow, ABC.Ui_MainWindow):
    # Список записей из файла excel
    records = []

    # Инициализатор
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.tableWidget.setColumnCount(6)
        self.tableWidget.setHorizontalHeaderLabels(['№',
                                                    'Поставщики',
                                                    'Товар',
                                                    'Потребность,\nшт.',
                                                    'Цена за 1 шт.,\nруб.',
                                                    'Ожидаемая\nокупаемость,\nруб.']
                                                   )
        self.tableWidget.setColumnWidth(0, 5)
        self.tableWidget.setColumnWidth(1, 150)
        self.tableWidget.setColumnWidth(2, 150)
        self.tableWidget.setColumnWidth(3, 90)
        self.tableWidget.setColumnWidth(4, 120)
        self.tableWidget.setColumnWidth(5, 120)
        self.tableWidget.setRowCount(0)
        self.tableWidget.verticalHeader().setVisible(0)
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        self.tableWidget_2.setColumnCount(6)
        self.tableWidget_2.setColumnWidth(0, 5)
        self.tableWidget_2.setColumnWidth(1, 150)
        self.tableWidget_2.setColumnWidth(2, 125)
        self.tableWidget_2.setColumnWidth(3, 150)
        self.tableWidget_2.setColumnWidth(4, 150)
        self.tableWidget_2.setColumnWidth(5, 55)
        self.tableWidget_2.setHorizontalHeaderLabels(['№',
                                                      'Товар',
                                                      'Ожидаемая\nокупаемость,\nруб.',
                                                      'Доля реализации\nпо позиции,\n%',
                                                      'Долея реализации\nпо позиции\nс нарастающим итогом,\n%',
                                                      'Группа'
                                                      ]
                                                     )
        self.tableWidget_2.setRowCount(0)
        self.tableWidget_2.verticalHeader().setVisible(0)
        self.tableWidget_2.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        self.pushButton.clicked.connect(self.loaddata)
        self.pushButton_2.clicked.connect(self.abcanaliz)
        self.pushButton_3.clicked.connect(self.createreport)

    # Заполняет список записей из файла excel
    def filldata(self):
        try:
            self.records.clear()
            if self.lineEdit.text() == '':
                raise NotImplementedError('Введен неправильный диапазон ячеек в excel листе.')
            scells = self.lineEdit.text().split(':')
            words = [chr(_) for _ in range(ord(scells[0][0]), ord(scells[1][0]) + 1)]
            scells = [int(_[1:]) for _ in scells]
            if words.__len__() != 6:
                raise NotImplementedError('Введен неправильный диапазон ячеек в excel листе.')
            wb = load_workbook('data.xlsx');
            sheet = wb['Лист1']
            for row in range(scells[0], scells[1] + 1):
                args = []
                for col in enumerate(words):
                    val = sheet[col[1] + row.__str__()].value
                    if col[0] == 5 or col[0] == 4:
                        val = round(val, 2)
                    if val is None:
                        raise NotImplementedError('Введен неправильный диапазон ячеек в excel листе.')
                    args.append(val)
                if col[0] == 5:
                    self.records.append(Record(*args))
                    args.clear()
        except TypeError:
            return 'Последняя колонка данных в excel листе должна быть заполнена цифрами, а не формулами.'
        except Exception as excep:
            return excep.__str__()
        finally:
            try:
                wb.close()
            except:
                pass
        return ''

    # Обработчик нажатия кнопки "Загрузить данные из excel"
    def loaddata(self):
        err = self.filldata()
        if err == '':
            self.showdata(self.tableWidget, ['number', 'supplier', 'good', 'need', 'price', 'income'])
            self.statusbar.showMessage('')
        else:
            self.statusbar.showMessage(err)

    # Выводит данные в указанную таблицу (верхнюю или нижнюю)
    def showdata(self, table: QTableWidget, collist):
        table.setRowCount(0)
        for rec in self.records:
            table.setRowCount(table.rowCount() + 1)
            for col in enumerate(collist):
                table.setItem(table.rowCount() - 1, col[0],
                              QTableWidgetItem(rec.__dict__[col[1]].__str__(), 0))

    # Обработчик нажатия кнопки "ABC анализ"
    def abcanaliz(self):
        ssum = sum([_.income for _ in self.records])
        for rec in self.records:
            rec.prez = round(rec.income / ssum * 100, 2)
        self.records.sort(key=lambda rec: rec.prez, reverse=True)
        val = 0
        for rec in self.records:
            rec.prezbig = round(round(val, 2) + rec.prez, 2)
            val = rec.prezbig
        for rec in self.records:
            if rec.prezbig <= 80:
                rec.group = 'A'
            elif rec.prezbig <= 95:
                rec.group = 'B'
            else:
                rec.group = 'C'
        self.showdata(self.tableWidget_2, ['number', 'good', 'income', 'prez', 'prezbig', 'group'])

    # Обработчик нажатия кнопки "Отчет"
    def createreport(self):
        if self.records.__len__() != 0:
            doc = Document()
            doc.add_heading('АВС анализ', 0).alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
            doc.add_paragraph().add_run(
                '               Ниже, в таблице представлены результаты проведенного АВС анализа.')
            doc.add_paragraph().add_run(
                '               Товары группы А это наиболее важные товары. Их запасы необходимо часто контролировать. ' +
                'Они требуют наиболшего учета. С этой группы требуется начинать управление запасами' +
                ' и тратить на нее наибольшее время. Доля в результате 80%.')
            doc.add_paragraph().add_run(
                '               Товары группы В это наиболее важные товары. Их запасы можно контролировать реже.' +
                ' Доля в результате 15%.')
            doc.add_paragraph().add_run(
                '               Группа С. Эти товары просто должны быть в наличии. Их запасы контролируются' +
                ' реже чем запасы предыдущих групп. Доля в результате 5%.')
            table = doc.add_table(rows=self.records.__len__() + 1, cols=9)
            table.style = 'Table Grid'
            hdr = table.rows[0].cells
            hdr[0].text = '№'
            hdr[1].text = 'П-к'
            hdr[2].text = 'Товар'
            hdr[3].text = 'Потр.,\nшт.'
            hdr[4].text = 'Ц.\nруб.'
            hdr[5].text = 'Ок-сть,\nруб.'
            hdr[6].text = 'Д.реал.\nпо поз.,\n%'
            hdr[7].text = 'Д.реал.\nпо поз.\nс нар.ит.,\n%'
            hdr[8].text = 'Гр.'
            flds = ['number', 'supplier', 'good', 'need', 'price', 'income', 'prez', 'prezbig', 'group']
            for rec in enumerate(self.records, 1):
                for col in range(0, 9):
                    table.rows[rec[0]].cells[col].text = rec[1].__dict__[flds[col]].__str__()
            doc.save('ABCAnaliz.docx')


# Главная функция приложения
def main():
    app = QtWidgets.QApplication(sys.argv)
    app.setStyleSheet(
        app.styleSheet() + " QTableWidget{gridline-color: #0000ff;}  QHeaderView::section{ border: 1px solid #0000ff;  border-bottom: 1px solid #0000ff; }");
    window = ExampleApp()
    window.show()
    app.exec_()


main()

Ответы (0 шт):