Телеграмм бот данные в excel

Время на прочтение
9 мин

Количество просмотров 49K

«История ничему не учит, а только наказывает за незнание уроков.»
(с) В.О. Ключевский

Друг предложил мне поработать над проектом для нашей кафедры. ТЗ пока не сформулировано, но точно известно, что это будет бот в телеге. Я хоть и питонист, но с ботами дел никогда не имел, поэтому пишу эту статью, как заметку, для себя и молодых перспективных ребят, чтоб у них было от чего оттолкнуться. Постараюсь писать максимально понятным и простым языком. Профессионалам тут особо делать не чего, хотя, может и придёт какая-нибудь идея.

Краткое описание бота

Наш бот будет создан на тематику Белого движения в гражданской войне в России (1917-1922) /сегодня разговор не о политике. Это просто пример/

  • По команде /start бот будет приветствие и посылать стикер;

  • После приветствия появится клавиатура под строкой набора сообщений с двумя кнопками «Вывести случайную цитату белогвардейца» и «Литература»

  • Нажатие на первую кнопку выведет рандомную цитату из excel файла (такое извращение нужно для подготовки к будущему проекту)

  • Нажатие на кнопку «Литература» выдаст инлайновую клавиатуру (далее будет прояснение, для тех кто не понял что это) с названиями произведений белогвардейских авторов или о белогвардейцах.После нажатия клавиатура пропадёт (просто этим навыком, думаю, необходимо обладать), начнётся загрузка pdf файла и появится оповещение «Приятного чтения!»

Вот такой простенький бот у нас по выйдет.

Начало. Создание бота и добавление библиотек.

Для начала добавим библиотеку pyTelegramBotAPI обычным пипом в cmd.

pip install pyTelegramBotAPI

А также загрузим простенькую библиотеку для работы с Excel. (ЧИТАЕТ ТОЛЬКО .xls!!!)

pip install xlrd

Время импортировать все необходимые библиотеки.

import telebot #импорт pyTelegramBotAPI 
from telebot import types #также достанем типы
import random #рандом обязательно
import xlrd #библиотка чтения экселевских файлов

Далее нужно создать самого бота в телеграме. Для этого пройдёмся по следующим шагам:

  1. Найти в поиске телеграма @BotFather

  2. Написать ему команду /newbot

  3. Первым сообщение отправить имя бота, а вторым его юзернейм (который пишется с @). Он должен быть уникальный и оканчиваться на Bot или _bot

После этих шагов батя пришлёт нам ссылку на нашёго бота и его API.

Нужно скопировать всю строку, которая на скрине закрыта красным прямоугольником

Нужно скопировать всю строку, которая на скрине закрыта красным прямоугольником

Если коротко, то API — это контракт, который предоставляет программа. «Ко мне можно обращаться так и так, я обязуюсь делать то и это».
(Более подробная инфа тут API)

Кодим

Раз библиотеки уже добавили, значит создаём переменную, определяющую бота с помощью API.

bot = telebot.TeleBot("TOKEN")

В начале, при написании команды /start, бот у нас выдаст приветствие. Соответственно, вставляем декоратор обработчика сообщений.

@bot.message_handler(commands=['start'])

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

Коротко: Декораторы — это, по сути, просто своеобразные «обёртки», которые дают нам возможность делать что-либо до и после того, что сделает декорируемая функция, не изменяя её.

Теперь наш бот понимает команду /start, но ещё ничего не делает. Создаём функцию приветственного сообщения.

@bot.message_handler(commands=['start'])
def send_welcome(message):
	stic = open('stic/welcome.webp', 'rb') #чтение файла в двоичном формате

	# клавиатура
	markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
	but1 = types.KeyboardButton("Вывести случайную цитату белогвардейца")
	but2 = types.KeyboardButton("Литература")
	markup.add(but1, but2)

	bot.reply_to(message, "Здравствуй, {0.first_name}nСмотрю, ты за Единую, Великую и Недилимую".format(message.from_user)
  ,parse_mode='html',reply_markup=markup)
	bot.send_sticker(message.chat.id,stic)

Пробежимся по коду

Строкой stic = open('stic/welcome.webp', 'rb') мы записываем в переменную путь к нашему стикеру в формате .webp (скачать его можно из сообщений телеграма правой кнопкой мыши, «сохранить как»)

Ниже происходит создание клавиатуры
markup = types.ReplyKeyboardMarkup(resize_keyboard=True) ,а точнее запись в переменную подстрочной клавиатуры. Параметр resize_keyboard=True подгоняет кнопки по высоте до возможного минимума. Также создаём две кнопочки и добавляем в клавиатуру:

but1 = types.KeyboardButton("Вывести случайную цитату белогвардейца")
but2 = types.KeyboardButton("Литература")
markup.add(but1, but2)

Клавиатура готова, но пока не используется. Пока оставим её и переключимся на сообщение. Одной строкой мы указываем боту отправить сообщение с текстом, именем отправителя ({0.first_name} , а вытягивает его он из.format(message.from_user) мы можем дописать .format(message.from_user, bot.get_me()) и вызвать имя бота, добавив в текст {1. first_name}), правилом оформления parse_mode='html' (также можно выбрать 'markdown') и определением клавиатуры, которую создали выше.

bot.reply_to(message, "Здравствуй, {0.first_name}nСмотрю, ты за Единую, Великую и Недилимую".format(message.from_user)
,parse_mode='html',reply_markup=markup)

Последней строкой отправляем стикер bot.send_sticker(message.chat.id,stic)

Приветственное сообщение и клавиатура

Приветственное сообщение и клавиатура

Время дать возможность боту коммуницировать

@bot.message_handler(func=lambda message: True)
def menu(message):
	if message.chat.type == 'private':
		if message.text == "Вывести случайную цитату белогвардейца":

			#достаём циататы из ворда
			rb = xlrd.open_workbook('citat/citat.xls', formatting_info=True)
			sheet = rb.sheet_by_index(0)
			for rownum in range(sheet.nrows):
				rand = int(random.randint(0,rownum))
				row = sheet.row_values(rand)
			bot.send_message(message.chat.id, row)


		elif message.text == "Литература":

			#инлайновая клавиатура
			inMurkup = types.InlineKeyboardMarkup(row_width=1)
			but1 = types.InlineKeyboardButton("И.Ф. Плотников - Александр Васильевич Колчак. Исследователь, адмирал, Верховный правитель России",callback_data='book1')
			but2 = types.InlineKeyboardButton("А.В. Туркул - Дроздовцы в огне", callback_data='book2')
			but3 = types.InlineKeyboardButton("П.Н. Врангель - Записки", callback_data='book3')
			but4 = types.InlineKeyboardButton("М.Г. Дроздовский - Дневник", callback_data='book4')
			inMurkup.add(but1, but2, but3, but4)

			bot.send_message(message.chat.id, "Книги на любой вкус", reply_markup=inMurkup)
		else:
			bot.send_message(message.chat.id, "Я не знаю что и ответить")

Букв много, но сейчас всё раскидаем. Берём знакомый декоратор и делаем проверку лямбдой сообщение. Если не в курсе что такое лямбда-функция, то сюда. Бот у нас работает через личные сообщения, поэтому пропишем if message.chat.type == 'private':, если требуется, то можете указать условия для “group”, “supergroup” или “channel” , но нам это не нужно.

Далее идёт строка с текстом. ВАЖНО текст должен совпадать с названием кнопки клавиатуры, которую указывали выше.

Создаём экселевский файлик, в первую колонку вписываем цитаты, сохраняем в формате .xls в папку, как делали со стикером.

Со спокойной душой вызываем на файл на чтение
rb = xlrd.open_workbook('citat/citat.xls', formatting_info=True), указываем лист с которого считываем инфу sheet = rb.sheet_by_index(0) индексы как у массива (первый элемент нулевой).

Далее определяем диапазон заполненных строк в листе и записываем их количество в rownum. Используем эту переменную как верхнюю границу до которой может сгенерироваться случайное число rand = int(random.randint(0,rownum)). Получив ячейку, вытаскиваем из неё значение row = sheet.row_values(rand) отправляем его bot.send_message(message.chat.id, row).

Вышло как-то так

Вышло как-то так

Для литературы будем использовать инлайновую клавиатуру.

elif message.text == "Литература":

	#инлайновая клавиатура
	inMurkup = types.InlineKeyboardMarkup(row_width=1)
	but1 = types.InlineKeyboardButton("И.Ф. Плотников - Александр Васильевич Колчак. Исследователь, адмирал, Верховный правитель России", callback_data='book1')
	but2 = types.InlineKeyboardButton("А.В. Туркул - Дроздовцы в огне", callback_data='book2')
	but3 = types.InlineKeyboardButton("П.Н. Врангель - Записки", callback_data='book3')
	but4 = types.InlineKeyboardButton("М.Г. Дроздовский - Дневник", callback_data='book4')
	inMurkup.add(but1, but2, but3, but4)

	bot.send_message(message.chat.id, "Книги на любой вкус", reply_markup=inMurkup)

Определяем клавиатуру inMurkup = types.InlineKeyboardMarkup(row_width=1) параметр row_width=1 говорит о том, что на одной строке будет одна кнопка. Принцип кнопок создания такой же как и у обычной клавиатуры, но появляется параметр callback_data значения которого примет бот после нажатия на кнопку и поймёт что нужно сделать (далле это всё опишем).

Последней строкой отправляем сообщение и цепляем к нему инлайновую клавиатуру.

Работа с callback_data

@bot.callback_query_handler(func=lambda call: True)
def callback_inline(call):
	try:
		if call.message:
			if call.data == 'book1':
				doc = open('boo/Plotnikov_Ivan-Aleksandr_Vasilevich_Kolchak_Issledovatel_admiral_Verhovnyi_pravitel_Rossii.pdf', 'rb')
				bot.send_document(call.message.chat.id, doc)
			elif call.data == 'book2':
				doc = open('boo/Turkul_-_Drozdovtsy_v_ogne.pdf','rb')
				bot.send_document(call.message.chat.id, doc)
			elif call.data == 'book3':
				doc = open('boo/Vrangel_P_Zapiski_a4.pdf', 'rb')
				bot.send_document(call.message.chat.id, doc)
			elif call.data == 'book4':
				doc = open('boo/Drozdovsky_dnevnik_1963__ocr.pdf', 'rb')
				bot.send_document(call.message.chat.id, doc)
			#удаляем инлайновую клаву
			bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text="Книги на любой вкус",
				reply_markup=None)
			#Создаём уведомление
			bot.answer_callback_query(callback_query_id=call.id, show_alert=False,
				text='Приятного чтения!')
	except Exception as e:
		print(repr(e))

Первым делом вызываем декоратор обработки колбэка и подтверждаем, что он был получен @bot.callback_query_handler(func=lambda call: True). Далее создаём функцию с конструкцией try-except (Что это? Чекай). Код хоть и приличный по объёму, но весь однотипный. Через if мы понимает какая «дата» пришла от кнопки, например
if call.data == 'book1': отвечает за первую кнопку с книгой про Колчака. Соответственно, командой

doc = open('boo/Plotnikov_Ivan-Aleksandr_Vasilevich_Kolchak_Issledovatel_admiral_Verhovnyi_pravitel_Rossii.pdf', 'rb')

мы создаём переменную doc в которую «суём» pdf файл, который сохранили в папку «boo» заранее.

Теперь строкой bot.send_document(call.message.chat.id, doc) отправляем файл в чат.

После леса из наших elif удалим инлайновую клавиатуру, дабы не мешалась. Действие необязательно, но мы же с вами тренируемся, поэтому пусть код будет здесь.

Вызываем функцию bot.edit_message_text По тексту определяется сообщение и
в параметр, который мы использовали для добавления клавиатуры reply_markup вносим значение None.

Уведомление призывается заклинанием

Параметр show_alert отвечает за вид оповещения (False простое временное уведомление, True уведомление с кнопкой «Ок»)

1 — False, 2 — True

1 — False, 2 — True

Завершаем эту ступень кода конструкцией проверки исключений (ошибок).

except Exception as e:
	print(repr(e))

Финальный аккорд:

bot.polling(none_stop=True)

Именно этой командой и закончим наш код. Теперь бот постоянно проверяет не написал ли ему кто.

В итоге получился такой код:

import telebot
from telebot import types
import random
import xlrd

bot = telebot.TeleBot("TOKEN")

@bot.message_handler(commands=['start'])
def send_welcome(message):
	stic = open('stic/welcome.webp', 'rb')

	# клавиатура
	markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
	but1 = types.KeyboardButton("Вывести случайную цитату белогвардейца")
	but2 = types.KeyboardButton("Литература")
	markup.add(but1, but2)

	bot.reply_to(message, "Здравствуй, {0.first_name}nСмотрю, ты за Единую, Великую и Недилимую".format(message.from_user),parse_mode='html',reply_markup=markup)
	bot.send_sticker(message.chat.id,stic)



@bot.message_handler(func=lambda message: True)
def menu(message):
	if message.chat.type == 'private':
		if message.text == "Вывести случайную цитату белогвардейца":

			#достаём циататы из ворда
			rb = xlrd.open_workbook('citat/citat.xls', formatting_info=True)
			sheet = rb.sheet_by_index(0)
			for rownum in range(sheet.nrows):
				rand = int(random.randint(0,rownum))
				row = sheet.row_values(rand)
			bot.send_message(message.chat.id, row)


		elif message.text == "Литература":

			#инлайновая клавиатура
			inMurkup = types.InlineKeyboardMarkup(row_width=1)
			but1 = types.InlineKeyboardButton("И.Ф. Плотников - Александр Васильевич Колчак. Исследователь, адмирал, Верховный правитель России", callback_data='book1')
			but2 = types.InlineKeyboardButton("А.В. Туркул - Дроздовцы в огне", callback_data='book2')
			but3 = types.InlineKeyboardButton("П.Н. Врангель - Записки", callback_data='book3')
			but4 = types.InlineKeyboardButton("М.Г. Дроздовский - Дневник", callback_data='book4')
			inMurkup.add(but1, but2, but3, but4)

			bot.send_message(message.chat.id, "Книги на любой вкус", reply_markup=inMurkup)
		else:
			bot.send_message(message.chat.id, "Я не знаю что и ответить")

#обработка callback
@bot.callback_query_handler(func=lambda call: True)
def callback_inline(call):
	try:
		if call.message:
			if call.data == 'book1':
				doc = open('boo/Plotnikov_Ivan-Aleksandr_Vasilevich_Kolchak_Issledovatel_admiral_Verhovnyi_pravitel_Rossii.pdf', 'rb')
				bot.send_document(call.message.chat.id, doc)
			elif call.data == 'book2':
				doc = open('boo/Turkul_-_Drozdovtsy_v_ogne.pdf','rb')
				bot.send_document(call.message.chat.id, doc)
			elif call.data == 'book3':
				doc = open('boo/Vrangel_P_Zapiski_a4.pdf', 'rb')
				bot.send_document(call.message.chat.id, doc)
			elif call.data == 'book4':
				doc = open('boo/Drozdovsky_dnevnik_1963__ocr.pdf', 'rb')
				bot.send_document(call.message.chat.id, doc)
			#удаляем инлайновую клаву
			bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text="Книги на любой вкус",
				reply_markup=None)
			#Создаём уведомление
			bot.answer_callback_query(callback_query_id=call.id, show_alert=False,
				text='Приятного чтения!')
	except Exception as e:
		print(repr(e))

bot.polling(none_stop=True)

Пара слов от автора

Если есть желание показать друзьям что наворотили, то запускайте код и всё будет работать, но если код остановить или выключить комп, то бот ничего выдавать не будет. Из этого выходит, что для полноценного бота просто необходим хостинг, что, как правило, платно.

Больше функций, параметров и всего прочего находится в документации. Справочник на русском. Библиотеки pyTelegramBotAPI и xlrd.

Огромное спасибо за прочтение статьи! Надеюсь она оказалась полезной. А если понравилась, то поднимай статью в рейтинге и оставляй комменты)

Автор обитает тут: ВК, Инстаграм

Организовать удобный учет и оцифровать процессы можно при помощи простейших и доступных всем инструментов. В данной публикации мы поделимся исходниками своей наработки, которую можно настроить по описанной инструкции или использовать как идею для реализации в своем бизнесе.

О чем пойдет речь

Мы, команда разработчиков helpexcel.pro, постоянно создаем готовые решения в Гугл таблицах для управленческого учета в малом бизнесе и бесплатно публикуем их в открытом доступе.

В этот раз мы поделимся своими наработками для учета небольшого склада. Это мини-сервис для учета небольшого склада, созданный на основе Гугл таблицы с возможностью ввода данных через Телеграм-бота.

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

Основные функции таблицы

Таблица устроена так, что в ней есть область для внесения справочников, область для учета приходов, область для учета событий и область аналитики. В качестве аналитики формируются отчеты о дебиторской и кредиторской задолженности, остатки по складу и расчет себестоимости.

В классическом виде представлены ABC и XYZ анализы товаров, что дает аналитику о том, в какие товары стоит дальше вкладываться.

Ниже делимся ссылкой на таблицу, но советуем вам ознакомиться с описанием, чтобы понять принцип ее устройства и использовать 100% возможностей.

Чтобы полноценно воспользоваться таблицей создайте ее копию на своем Гугл диске.

Описание работы таблицы

Для нас это уже не первая версия складской таблицы, и мы предусмотрели потребности пользователей в разных способах подсчета закупочной цены.Для корректного подсчета прибыли, рентабельности и ценности товаров на складе нужно выбрать метод расчета закупочной цены. Настройка находится на листе “Справочник”:

В рамках функций таблицы заложено 3 вида расчета: по средней цене прихода, метод FIFO и метод LIFO.

По средней цене прихода

Этот метод принимает за себестоимость среднее значение за указанный вами период.

Возьмем для примера период в 1 месяц.

Месяц назад закупочная цена была 1000 рублей, 16 дней назад — 1050 рублей, а 3 дня назад — 1000 рублей.

Для данного метода принимается средняя закупочная цена — 1050 рублей.

Метод FIFO

«Первым пришёл — первым ушёл»

Разберем этот принцип на примере. Вы приобрели 2 принтера по 5 000 ₽ за шт. и ещё два абсолютно таких же, но уже по 6 000 ₽.

У вас хотят купить один из них. Для продавца не важно, какой из них взять — они одинаковые. Но бухгалтеру важна общая стоимость товара на складе.

По методу FIFO нужно взять принтер, который поступил на склад раньше всех. То есть за 5 000 рублей.

В таком случае на складе останется 1 принтер стоимостью 5 000 рублей и 2 принтера за 6 000 рублей.

Общая стоимость 3-х принтеров на складе — 17 000 рублей.

Метод LIFO

«Последним пришёл — первым ушёл»

Для удобства возьмем тот же пример с принтерами. Все суммы и количества оставим теми же.

По методу LIFO мы должны взять принтер, который поступил на склад позже всех. За 6 000 рублей.

Тогда на складе останется 2 принтера стоимостью 5 000 рублей и 1 принтер стоимостью 5 000 рублей.

Стоимость оставшихся 3-х принтеров — 16 000 рублей.

Продолжаем заполнять справочник таблицы переменными. Укажите ваш часовой пояс, заполните справочники товаров, поставщиков и покупателей.

Далее переходим к учетной части таблицы.

Принцип работы каждого листа рассмотрим по отдельности.

Лист закупки

Информация о всех пополнениях склада фиксируется на данном листе или через Телеграм-бота.

Некоторые поля таблицы расчетные, в них работают формулы — не заполняйте эти столбцы.

Для обеспечения хранения большого числа строк и возможности связи с ботом к таблице подключена внешняя база данных. Для просмотра исторической информации можно выбрать период и нажать кнопку “обновить”.За счет этой настройки мы ускорили работу таблицы и не выводим невостребованные строки с данными.

Если же какая-то позиция была введена по ошибке или уже не актуальна, то ее можно удалить. Для этого в последнем столбце выделите галочкой нужные строки и нажмите на кнопку “удалить”.

Для ввода данных через telegram-бота нужно перейти по ссылке https://t.me/help_excel_storage_bot. Если вы правильно выполнили настройку бота, то у вас появится блок из 4-х кнопок:

Выберите “Закупки”.

Далее, следуя диалогу бота, вы вводите информацию о закупке. Поля диалога бота идентичны полям таблицы.

Для отображения информации, введенной через бота, нужно нажать кнопку “обновить”.

Лист отгрузки

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

В правой части таблицы представлена область расчета себестоимости и показателей дохода от реализации товара. Показатели рассчитываются при нажатии на кнопку “обновить” или “сохранить”.

Лист аналитики

Данный лист состоит из трех блоков.

Область расчета складских запасов:

Дебиторская и кредиторская задолженность:

Сумма задолженности отражается в столбце “задолженность” если вы не поставили галочку напротив суммы в столбце “статус оплаты”. Тогда таблица считает, что платеж еще не проведен.

Также, если вы поставили в столбце “дней отсрочки” количество дней, и эта дата уже прошла, то сумма будет отражена в столбце “просроченная задолженность”.

Лист ABC анализа

Все товары делятся на 3 группы::

А: приносят 80% продаж

В: приносят 15% продаж

С: приносят 5% продаж

Лист XYZ анализа

Отчет показывает колебания спроса, товары разбиваются на 3 группы:.

X — товары продаются стабильно в течение года.

Категория Y — товары сезонного спроса.

Категория Z — спрос нерегулярен, какие-либо тенденции отсутствуют.

Лист ABC XYZ

На данном листе объединяется информация ABC и XYZ анализа. Товарная матрица делится на 9 групп:

  • AX – приносящие значительную долю выручки со стабильным спросом;
  • AY – большая доля выручки, но спрос подвержен колебаниям;
  • AZ – хорошо продаются, но спрос плохо поддается прогнозированию;
  • BX – средние объемы выручки, низкие колебания спроса;
  • BY – средние объемы выручки, колебания спроса в пределах нормы, например, сезонные;
  • BZ – средние объемы выручки, сложно прогнозируемый спрос;
  • CX – низкая доля в прибыли, стабильный уровень спроса;
  • CY – невысокий уровень прибыли при средних колебаниях спроса;
  • CZ – низкий уровень прибыли, высокие колебания спроса.

Пример:

Настройка таблицы

Для начала нужно создать копию таблицы, как показано на картинке ниже:

В таблицу встроен скрипт, который считает себестоимость товаров. Для того, чтобы таблица работала правильно, нужно авторизоваться. Для этого нажмите на значок обновления на листе “Отгрузки”:

У вас появится такое поле:

Нажмите на “Продолжить”.

Выберите свой google-аккаунт

В появившемся окне нажмите на “Дополнительные настройки”:

Затем, на “Перейти на страницу “script”:

В следующем окне пролистайте вниз и нажмите на кнопку “Разрешить”:

Отлично, авторизация скрипта пройдена!

Настройка Telegram-бота

Основное предназначение бота — ввод данных о приходах и отгрузках в таблицу. Он служит больше как вспомогательный интерфейс для возможности мобильного ввода информации.

Для его настройки вам нужно на листе “Пользователи бота” добавить номера сотрудников, которые будут работать с ботом.

Номер телефона обязательно нужно ввести через цифру 7, без “+” и других дополнительных знаков. Так, как показано на скриншоте.

После нажатия на кнопку сохранить вам нужно будет принять соглашение об обработке данных.

Затем вам нужно перейти на страницу бота @help_excel_storage_bot.

В диалоге с ботом следует нажать на кнопку “Запустить” (если вы через ПК) или на кнопку “Старт” (если вы через телефон):

После этого также нужно будет принять соглашение об обработки данных и ввести свой телефон в формате +7##########.

На этом настройка чат-бота окончена. Подробное описание работы чат-бота и таблицы будет далее.

Спасибо, что полностью ознакомились с нашим руководством!

Если у вас еще останутся вопросы по таблице, то можете задать их в нашем телеграмм-чате:

0 / 0 / 0

Регистрация: 07.11.2021

Сообщений: 10

1

07.11.2021, 19:40. Показов 6557. Ответов 2


Студворк — интернет-сервис помощи студентам

Хочу совместить вместе Telegram и Python.
Оба коды работают без ошибок, много над ними замучился я.
Внизу коды:
1. Для ответа в телеграм боте;
2. Для импорта нужных данных из Excel по поиску

Нужно сделать так чтобы, когда в боте что та написали, он начал искать это в файле Excel и ответил ползователю.
Если есть другие варианты кода, то я буду рад узнать.

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
import logging
from aiogram import Bot, Dispatcher, executor, types
 
#Токен
TOKEN = "token"
 
#Обязательно
logging.basicConfig(level=logging.INFO) 
 
#Подключение к токену
bot = Bot(token=TOKEN)
#Подключение к bot
dp = Dispatcher(bot)
 
#Для ответа на команды
@dp.message_handler(commands=['start', 'help'])
async def send_welcome(message: types.Message):
    #Ответ
     await message.reply("Hi!nI'm EchoBot!nPowered by aiogram.")
 
#Чтобы ответила на конкретный текст
@dp.message_handler(text="text")
async def echo(message: types.Message):
    #Чтобы ответила на текст что то
    await message.answer("»")
 
#Чтобы ответил на любой текст
@dp.message_handler()
async def echo(message: types.Message):
     #Чтобы повтярял текст
    await message.answer(message.text)
 
 
#Обязательно
if __name__ == '__main__': 
    executor.start_polling(dp, skip_updates=True)
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
import logging
from aiogram import Bot, Dispatcher, executor, types
 
#Токен
TOKEN = "token"
 
#Обязательно
logging.basicConfig(level=logging.INFO) 
 
#Подключение к токену
bot = Bot(token=TOKEN)
#Подключение к bot
dp = Dispatcher(bot)
 
#Для ответа на команды
@dp.message_handler(commands=['start', 'help'])
async def send_welcome(message: types.Message):
    #Ответ
     await message.reply("Hi!nI'm EchoBot!nPowered by aiogram.")
 
#Чтобы ответила на конкретный текст
@dp.message_handler(text="text")
async def echo(message: types.Message):
    #Чтобы ответила на текст что то
    await message.answer("»")
 
#Чтобы ответил на любой текст
@dp.message_handler()
async def echo(message: types.Message):
     #Чтобы повтярял текст
    await message.answer(message.text)
 
 
#Обязательно
if __name__ == '__main__': 
    executor.start_polling(dp, skip_updates=True)



0



Действительно, реализовать такое можно, но использовать для этих целей Excel — не лучшая идея. Почему? .xls это простой файл, считывание таких файлов относительно медленная операция, особенно с учетом того, что считывание экселя обычно значительно замедляется при увеличении количества данных (а что если у вас будет 10000 наименований мебели?) а так же с учетом того, что библиотека, которая его читает должна кроме прочего спарсить такой файл в удобный для работы в питоне объект (например в словарь или список). Такая задача, возможно, требует другого подхода.

Возможно вы скажете, что в вашей текущей задаче такой проблемы не появится, но ведь этот ответ в Т.Ч. для будущих поколений и для помощи вам в решении будущих задач :)

Теоретически (если вашей мебели действительно всего +-200 экземпляров) можно хранить всё в Json файле, примерно так:

[     
    {
        "name": "Черный стол",
        "sizes": "100x200x300",
        "color": "black",
        "description": "самый лучший стол"
    },
    {
        "name": "Синий стул",
        "sizes": "146x300x69",
        "color": "blue",
        "description": "самый лучший стул для лучшего стола"
    },
    {
        "name": "Шкаф",
        "sizes": "2x2",
        "color": "purple",
        "description": "Кто вообще заказал фиолетовый шкаф?"
    }
]

Для работы с Json в Python есть готовый модуль json, а его считывание, запись и парсинг происходят весьма быстро, но такой подход все ещё будет не очень хорошо работать для большого количества данных, хотя к преимуществам можно отнести возможность создания произвольной структуры:
Для каждой мебели вы можете указывать те поля, которые хотите, например сделать объект без поля цвет, без описания, или добавить к шкафу параметр наличия отдельной антресоли.

Однако раз (судя по вашему вопросу) вы имеете четкую структуру описания каждого объекта, возможно данное «преимущество» вам не нужно, тогда вы можете прибегнуть к более традиционному способу: использовать Базу данных

База данных имеет много преимуществ, к основным можно отнести следующие:

  • Высокая скорость работы (относительно прошлых способов)
  • Возможность общего доступа (например если кроме вашего бота информацию из неё будет читать ещё ваш сайт, или если вы захотите подключиться к ней из вне и внести изменения) Согласитесь, удобнее зайти в браузер и поменять всё оттуда, а не подключаться к файловой системе сервера, открывать файл, копировать, вставлять и т.д.
  • Определение правил безопасности (В базе данных можно легко ограничить права разных пользователей, например, чтобы вы могли вносить любые правки, а ваш менеджер мог лишь смотреть на них)
  • Определение связей данных (например, если вы хотите всегда знать к какому шкафу в комплекте идет данная антресоль, или к какому кухонному комплекту можно заказать в комплекте данный стол.

Более подробно о преимуществах вы можете узнать в интернете :)

Я же попробую показать пример кода работы с sqlite3 базой данных. Она имеет много ограничений, в сравнении с более «правильным» базами данных, такими как MySQL, PostgreSQL, Oracle и т.п. Но имеет очень важное преимущество: она не требует дополнительных настроек и установок, а её использование достаточно просто, например Python имеет встроенный модуль для работы с sqlite3 базами данных, в то время как для работы с postgreSQL понадобится установка дополнительных библиотек, например psycopg2.

Попробую представить небольшой фрагмент (Очень упрощенный) Создания базы данных и добавления в неё информации:

import sqlite3 as sl

con = sl.connect('furniture.db')
try:
    with con:
        con.execute("""
            CREATE TABLE furniture (
                id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
                name VARCHAR(255),
                size VARCHAR(255),
                color VARCHAR(255),
                description TEXT
            );
        """)
except sl.OperationalError:
    print('База данных уже создана. Пропускаем этот этап')

# Записываем в базу какие-то записи
sql = 'INSERT INTO furniture (name, size, color, description) values( ?, ?, ?, ?)'
data = [ 
    ('Черный стол', '100x200x300', 'black', 'самый лучший стол'),
    ('Синий стул', '146x300x69', 'blue', 'самый лучший стул для лучшего стола'),
    ('Шкаф', '2x2', 'purple', 'Кто вообще заказал фиолетовый шкаф?')
]  # data Может быть любыми вашими записями, как вы их запишите, это лишь ваше дело
with con:
    con.executemany(sql, data)

Надеюсь пока не слишком сложно? После запуска данного кода в базе мы увидим следующую картину:

Сразу отвечу на возможно возникший вопрос тех, кто впервые столкнулся с базами данных, и не понимает, что это за странные буквы аля CREATE TABLE — это специальный язык SQL. Почти все реляционные базы данных (например все упомянутые выше) управляются при помощи этого языка, не стоит пугаться раньше времени, основы его очень просты например здесь можно изучить весь основной синтаксис за 20 минут.

Скорее всего, запуск данного кода, с заполнением базы данных вы хотите выполнять редко: при поступлении новых товаров, например раз в неделю. В остальное время вам, скорее всего нужно будет читать содержимое. Давайте рассмотрим пример:

Вот так можно сделать чтение всех записей из таблицы:

import sqlite3 as sl

con = sl.connect('furniture.db')

with con:
    data = con.execute("SELECT * FROM furniture")
    for row in data:
        print(f'{row[4]} размером {row[2]} и с цветом "{row[3]}"')

Согласитесь, не очень сложно?

Вот что мы получим в консоли:
введите сюда описание изображения

А как известно простое правило гласит:

Всё что можно вывести в консоль, можно вывести и в telegram бота.

Но ведь нам нужно получать только конкретную мебель по названию? Да без проблем:

import sqlite3 as sl

con = sl.connect('furniture.db')

furniture_name = 'Черный стол'

with con:
    data = con.execute("SELECT * FROM furniture WHERE name=?", [furniture_name])
    res = data.fetchone()
    if not res:
        print('Мебель не найдена')
    else:
        print(res)

При этом в выводе мы увидим всю информацию об искомом столе:
введите сюда описание изображения

И при этом логику вы можете легко подстроить под себя: находить только те модели, которые есть на складе, возможно пользователь захочет увидеть всю черную мебель и т.д. всю логику фильтрации (если вы сделаете её при помощи SQL) будет брать на себя БД, а она делает это куда быстрее питона (хорошо видно на большом количестве записей)

Но вы же всё-таки спрашивали про Excel, и я говорил, что можно сделать через excel? Ну, за слова надо отвечать. Вот так выглядит мой excel файл:
excel

А вот как выглядит его считывание:

import pandas as pd

xl = pd.ExcelFile('db.xlsx')

df1 = xl.parse(xl.sheet_names[0])
hist_data = df1.to_numpy().tolist()

for el in hist_data:
    print(el)

результат

Сразу оговорись, я использую pandas и openpyxl, потому что новые .xlsx файлы библиотека xlrd обрабатывать не умеет.

Вам может показаться, что данный скрипт куда проще, Но за это приходится дорого платить: В то время как скрипт читающий записи из базы у меня выполняется ~0.3 секунды, этот уже целых 2! И будьте уверены, чем больше будет записей, тем больше будет разрыв.

Более того, скрипт записи отрабатывает ещё дольше, около 3х секунд:

import pandas as pd

#xl = pd.ExcelFile('db1.xlsx', )
data = [
    [1, 'Черный стол', '100x200x300', 'black', 'самый лучший стол'],
    [2, 'Синий стул', '146x300x69', 'blue', 'самый лучший стул для лучшего стола'],
    [3, 'Шкаф', '2x2', 'purple', 'Кто вообще заказал фиолетовый шкаф?']
]

df = pd.DataFrame(data)
df = df.transpose()
df.to_excel('db.xlsx')

Но при его работе получается другая структура документа:
введите сюда описание изображения

А значит, нужно либо учитывать это при считывании, либо изменять структуру получаемого файла под себя. Причем я, например, не смог в приемлемые сроки найти в интернете понятный гайд, как это сделать. Хотя нужные мне подсказки по работой с базе данных я нашел по первым же ссылкам.

Да, возможно есть и более быстрые способы работы с Excel, но они, очевидно, будут более сложными и менее понятными.

Исходя из всего выше перечисленного, как я уже сказал, для таких целей нужно использовать базу данных, ведь именно для этого они и придуманы.

Понравилась статья? Поделить с друзьями:
  • Текущий столбец excel vba
  • Телефоны которые читают word
  • Текущий месяц в excel текстом
  • Телефонный справочник в excel готовый шаблон скачать
  • Текущий месяц в excel автоматически