Блог им. Albus

Качаем котировки с Финама

Недавно начал учить язык программирования Python. Жаль, что я к нему приступил в 36 лет, а не в 16. Он прекрасно подходит для анализа исторических данных. Выкладываю скрипт, который заходит на сайт финама, скачивает оттуда котировки акций и записывает их в файл quotes.txt. Для того, чтобы всё работало, должен быть установлен Питон https://www.python.org/.
---
В интернете есть информация, как качать котировки с Финама не вручную, а с помощью скрипта. Вот эти статьи. Ими я пользовался при написании своего кода:
Программный сбор данных о котировках
Загрузка котировок валют с сайта finam.ru
Дополнительно пришлось хорошенько поработать головой, чтобы адаптировать эту информацию для моих нужд. Там кое-что устарело и коды авторов потребовали доработки. Также в моём скрипте вы найдёте цифровые символы, которые соответствуют каждой акции. Например Алроса лежит на сайте финама под цифрой 81820.
Дополнительные библиотеки не нужны, всё должно работать сразу без дополнительных правок.
Я снабдил код описанием, чтобы было понятно в какой строчке что происходит.
Главная задача скрипта — составить строку вида 
export.finam.ru/SBER_20170101_20171231.csv?market=0&em=3&code=SBER&apply=0&df=1&mf=0&yf=2017&from=2017-01-01&dt=31&mt=11&yt=2017&to=2017-12-31&p=7&f=SBER_20170101_20171231&e=.csv&cn=SBER&dtf=1&tmf=1&MSOR=0&mstime=on&mstimever=1&sep=1&sep2=1&datf=1&at=1
она улетит на сервер финама, и в ответ прилетит файл с нужными котировками.
Вот какая информация в нём будет:
Качаем котировки с Финама
Скачать код скрипта:
https://yadi.sk/i/Iaz5EvbovXei3A
Можно не качать, а скопировать отсюда:
from urllib.parse import urlencode
from urllib.request import urlopen
from datetime import datetime
#пользовательские переменные
ticker="SBER" #задаём тикер
period=7 # задаём период. Выбор из: 'tick': 1, 'min': 2, '5min': 3, '10min': 4, '15min': 5, '30min': 6, 'hour': 7, 'daily': 8, 'week': 9, 'month': 10
start = "01.01.2017" #с какой даты начинать тянуть котировки
end = "31.12.2017" #финальная дата, по которую тянуть котировки
########
periods={'tick': 1, 'min': 2, '5min': 3, '10min': 4, '15min': 5, '30min': 6, 'hour': 7, 'daily': 8, 'week': 9, 'month': 10}
print ("ticker="+ticker+"; period="+str(period)+"; start="+start+"; end="+end)
#каждой акции Финам присвоил цифровой код:
tickers={'ABRD':82460,'AESL':181867,'AFKS':19715,'AFLT':29,'AGRO':399716,'AKRN':17564,'ALBK':82616,'ALNU':81882,'ALRS':81820,'AMEZ':20702,'APTK':13855,'AQUA':35238,'ARMD':19676,'ARSA':19915,'ASSB':16452,'AVAN':82843,'AVAZ':39,'AVAZP':40,'BANE':81757,'BANEP':81758,'BGDE':175840,'BISV':35242,'BISVP':35243,'BLNG':21078,'BRZL':81901,'BSPB':20066,'CBOM':420694,'CHEP':20999,'CHGZ':81933,'CHKZ':21000,'CHMF':16136,'CHMK':21001,'CHZN':19960,'CLSB':16712,'CLSBP':16713,'CNTL':21002,'CNTLP':81575,'DASB':16825,'DGBZ':17919,'DIOD':35363,'DIXY':18564,'DVEC':19724,'DZRD':74744,'DZRDP':74745,'ELTZ':81934,'ENRU':16440,'EPLN':451471,'ERCO':81935,'FEES':20509,'FESH':20708,'FORTP':82164,'GAZA':81997,'GAZAP':81998,'GAZC':81398,'GAZP':16842,'GAZS':81399,'GAZT':82115,'GCHE':20125,'GMKN':795,'GRAZ':16610,'GRNT':449114,'GTLC':152876,'GTPR':175842,'GTSS':436120,'HALS':17698,'HIMC':81939,'HIMCP':81940,'HYDR':20266,'IDJT':388276,'IDVP':409486,'IGST':81885,'IGST03':81886,'IGSTP':81887,'IRAO':20516,'IRGZ':9,'IRKT':15547,'ISKJ':17137,'JNOS':15722,'JNOSP':15723,'KAZT':81941,'KAZTP':81942,'KBSB':19916,'KBTK':35285,'KCHE':20030,'KCHEP':20498,'KGKC':83261,'KGKCP':152350,'KLSB':16329,'KMAZ':15544,'KMEZ':22525,'KMTZ':81903,'KOGK':20710,'KRKN':81891,'KRKNP':81892,'KRKO':81905,'KRKOP':81906,'KROT':510,'KROTP':511,'KRSB':20912,'KRSBP':20913,'KRSG':15518,'KSGR':75094,'KTSB':16284,'KTSBP':16285,'KUBE':522,'KUNF':81943,'KUZB':83165,'KZMS':17359,'KZOS':81856,'KZOSP':81857,'LIFE':74584,'LKOH':8,'LNTA':385792,'LNZL':21004,'LNZLP':22094,'LPSB':16276,'LSNG':31,'LSNGP':542,'LSRG':19736,'LVHK':152517,'MAGE':74562,'MAGEP':74563,'MAGN':16782,'MERF':20947,'MFGS':30,'MFGSP':51,'MFON':152516,'MGNT':17086,'MGNZ':20892,'MGTS':12984,'MGTSP':12983,'MGVM':81829,'MISB':16330,'MISBP':16331,'MNFD':80390,'MOBB':82890,'MOEX':152798,'MORI':81944,'MOTZ':21116,'MRKC':20235,'MRKK':20412,'MRKP':20107,'MRKS':20346,'MRKU':20402,'MRKV':20286,'MRKY':20681,'MRKZ':20309,'MRSB':16359,'MSNG':6,'MSRS':16917,'MSST':152676,'MSTT':74549,'MTLR':21018,'MTLRP':80745,'MTSS':15523,'MUGS':81945,'MUGSP':81946,'MVID':19737,'NAUK':81992,'NFAZ':81287,'NKHP':450432,'NKNC':20100,'NKNCP':20101,'NKSH':81947,'NLMK':17046,'NMTP':19629,'NNSB':16615,'NNSBP':16616,'NPOF':81858,'NSVZ':81929,'NVTK':17370,'ODVA':20737,'OFCB':80728,'OGKB':18684,'OMSH':22891,'OMZZP':15844,'OPIN':20711,'OSMP':21006,'OTCP':407627,'PAZA':81896,'PHOR':81114,'PHST':19717,'PIKK':18654,'PLSM':81241,'PLZL':17123,'PMSB':16908,'PMSBP':16909,'POLY':175924,'PRFN':83121,'PRIM':17850,'PRIN':22806,'PRMB':80818,'PRTK':35247,'PSBR':152320,'QIWI':181610,'RASP':17713,'RBCM':74779,'RDRB':181755,'RGSS':181934,'RKKE':20321,'RLMN':152677,'RLMNP':388313,'RNAV':66644,'RODNP':66693,'ROLO':181316,'ROSB':16866,'ROSN':17273,'ROST':20637,'RSTI':20971,'RSTIP':20972,'RTGZ':152397,'RTKM':7,'RTKMP':15,'RTSB':16783,'RTSBP':16784,'RUAL':414279,'RUALR':74718,'RUGR':66893,'RUSI':81786,'RUSP':20712,'RZSB':16455,'SAGO':445,'SAGOP':70,'SARE':11,'SAREP':24,'SBER':3,'SBERP':23,'SELG':81360,'SELGP':82610,'SELL':21166,'SIBG':436091,'SIBN':2,'SKYC':83122,'SNGS':4,'SNGSP':13,'STSB':20087,'STSBP':20088,'SVAV':16080,'SYNG':19651,'SZPR':22401,'TAER':80593,'TANL':81914,'TANLP':81915,'TASB':16265,'TASBP':16266,'TATN':825,'TATNP':826,'TGKA':18382,'TGKB':17597,'TGKBP':18189,'TGKD':18310,'TGKDP':18391,'TGKN':18176,'TGKO':81899,'TNSE':420644,'TORS':16797,'TORSP':16798,'TRCN':74561,'TRMK':18441,'TRNFP':1012,'TTLK':18371,'TUCH':74746,'TUZA':20716,'UCSS':175781,'UKUZ':20717,'UNAC':22843,'UNKL':82493,'UPRO':18584,'URFD':75124,'URKA':19623,'URKZ':82611,'USBN':81953,'UTAR':15522,'UTII':81040,'UTSY':419504,'UWGN':414560,'VDSB':16352,'VGSB':16456,'VGSBP':16457,'VJGZ':81954,'VJGZP':81955,'VLHZ':17257,'VRAO':20958,'VRAOP':20959,'VRSB':16546,'VRSBP':16547,'VSMO':15965,'VSYD':83251,'VSYDP':83252,'VTBR':19043,'VTGK':19632,'VTRS':82886,'VZRZ':17068,'VZRZP':17067,'WTCM':19095,'WTCMP':19096,'YAKG':81917,'YKEN':81766,'YKENP':81769,'YNDX':388383,'YRSB':16342,'YRSBP':16343,'ZHIV':181674,'ZILL':81918,'ZMZN':556,'ZMZNP':603,'ZVEZ':82001}
FINAM_URL = "http://export.finam.ru/"# сервер, на который стучимся
market = 0 #можно не задавать. Это рынок, на котором торгуется бумага. Для акций работает с любой цифрой. Другие рынки не проверял.
#Делаем преобразования дат:
start_date = datetime.strptime(start, "%d.%m.%Y").date()
start_date_rev=datetime.strptime(start, '%d.%m.%Y').strftime('%Y%m%d')
end_date = datetime.strptime(end, "%d.%m.%Y").date()
end_date_rev=datetime.strptime(end, '%d.%m.%Y').strftime('%Y%m%d')
#Все параметры упаковываем в единую структуру. Здесь есть дополнительные параметры, кроме тех, которые заданы в шапке. См. комментарии внизу:
params = urlencode([
					('market', market), #на каком рынке торгуется бумага
					('em', tickers[ticker]), #вытягиваем цифровой символ, который соответствует бумаге.
					('code', ticker), #тикер нашей акции
					('apply',0), #не нашёл что это значит. 
					('df', start_date.day), #Начальная дата, номер дня (1-31)
					('mf', start_date.month - 1), #Начальная дата, номер месяца (0-11)
					('yf', start_date.year), #Начальная дата, год
					('from', start_date), #Начальная дата полностью
					('dt', end_date.day), #Конечная дата, номер дня	
					('mt', end_date.month - 1), #Конечная дата, номер месяца
					('yt', end_date.year), #Конечная дата, год
					('to', end_date), #Конечная дата
					('p', period), #Таймфрейм
					('f', ticker+"_" + start_date_rev + "_" + end_date_rev), #Имя сформированного файла
					('e', ".csv"), #Расширение сформированного файла
					('cn', ticker), #ещё раз тикер акции	
					('dtf', 1), #В каком формате брать даты. Выбор из 5 возможных. См. страницу https://www.finam.ru/profile/moex-akcii/sberbank/export/
					('tmf', 1), #В каком формате брать время. Выбор из 4 возможных.
					('MSOR', 0), #Время свечи (0 - open; 1 - close)	
					('mstime', "on"), #Московское время	
					('mstimever', 1), #Коррекция часового пояса	
					('sep', 1), #Разделитель полей	(1 - запятая, 2 - точка, 3 - точка с запятой, 4 - табуляция, 5 - пробел)
					('sep2', 1), #Разделитель разрядов
					('datf', 1), #Формат записи в файл. Выбор из 6 возможных.
					('at', 1)]) #Нужны ли заголовки столбцов
url = FINAM_URL + ticker+"_" + start_date_rev + "_" + end_date_rev + ".csv?" + params #урл составлен!
print("Стучимся на Финам по ссылке: "+url)
txt=urlopen(url).readlines() #здесь лежит огромный массив данных, прилетевший с Финама.
local_file = open('quotes.txt', "w") #задаём файл, в который запишем котировки.
for line in txt: #записываем свечи строку за строкой. 
	local_file.write(line.strip().decode( "utf-8" )+'\n')	
local_file.close()
print("Готово. Проверьте файл quotes.txt в папке где лежит скрипт")

П.С. 1. Напомню, что вручную котировки с Финама качаются здесь: https://www.finam.ru/profile/moex-akcii/sberbank/export/
П
.С. 2. Скрипт отправляет на Финам такую же строку, которую вы видите в «загрузках», когда качаете котировки вручную. Скрипт воспроизводит точно такой же адрес.
Скриншот файла, скачанного вручную без скрипта:
Качаем котировки с Финама
★82 | ₽ 236
У меня ребёнок начал учить питон в 7 лет.
Частная школа.
Хочет написать свою игру.
Максим Барбашин, у меня ещё в 90-е был советский компьютер, который в качестве монитора использовал ламповый телевизор. Я там кодил на бейсике (рисовал фигуры из линий, зная нотную грамоту, задавал мелодии типа Yesterday). Но с тех пор всё забыл и много лет не возвращался.

Albus (Игорь Китаев), 
Он у меня еще unity изучает.
Это все-таки больше подходит для ребенка.
Заинтересовался VR.
Я говорю, не знаю, чем тебе помочь.
Даже школ не нашел в стране, где могут этому научить.

Максим Барбашин, помогите ему сфокусироваться на чем-то одном. Unity подойдет. VR — это мертвая тема. Там нужно еще минимум пару витков (предыдущий был в конце 90-х). 
avatar

bstone

bstone, 
Была новогодняя елка в хай-тек стиле.
Дед Мороз в виде робота, VR Снегурочка и все такое.
Смотрю, мой ребенок круги вокруг ноута нарезает.
Он увидел знакомый интерфейс unity и решил выяснить подробности.
Снегурочку удалось спасти…
Albus (Игорь Китаев), Кворум 128? Тоже с него начинал.
avatar

ger_man

Albus (Игорь Китаев), и у меня до сих пор лежит на антресолях, еще рабочий! :D
avatar

Shadow

Shadow, я скучаю по тем стареньким играм, которые загружались с магнитофонных кассет :)
Albus (Игорь Китаев), встречал эмуляторы ZX Spectrum на просторах интернета, а также образы игр и программ к ним. При желании можно установить такой набор на Windows или Android-планшет и поностальгировать. :)))

P.S.: Для эстетов предусмотрен режим загрузки «в реальном времени» — с ожиданием по несколько минут и звуковым сопровождением из шипения, с бегающими полосками на экране… ))))
avatar

Shadow

Albus (Игорь Китаев), да было дело)))
Атари до сих пор у родителей где то лежит в полном боекомплекте )), Синклер тоже с ним же)
на Атари  тоже было можно кодить )
спасибо за пост, коллега!)
avatar

Dio

Shadow, 
Наверное, стоит как антиквариат?
Максим Барбашин, к сожалению, теперь только пыль собирает. )))) А также рядом с ним пара джойстиков и несколько кассет с играми. )))) Полный комплект, только по причине морального устаревания использовать его нет никакого смысла. Оставлю потомкам — показать, на чем раньше дедушки работали. :D
avatar

Shadow

Максим Барбашин, нафига ребенку в 7 программирование? Кодера эникейшика хотите вырастить? Пусть фундаментальные науки изучает, в начальной школе то уж точно.
avatar

Dmitry

Dmitry, полагаю что программирование так же развивает мозг ребенка, как изучение иностранного языка для общения. Учитывая то, что он в будущем сможет применять полученные знания, если выучит конечно, и зарабатывать на этом уже в школьные годы, то навык явно не лишний)
Friendly Deep Space, да и спекулировать акциями можно учить с 7 лет. Мозг отлично развивает. Но всему свое время. В школе надо учить математику, физику, языки и т.д. А прикладные знания на то и прикладные.
avatar

Dmitry

Dmitry, не совсем корректное сравнение имхо) Программирование это инструмент, причем универсальный) А спекулирование акциями это спекулирование акциями.
Friendly Deep Space, чем он универсальный? Тут речь даже не про основы алгоритмизации и т.д. А про изучение конкретного языка/платформы, очень прикладные знания. Причем быстро устаревающие.
avatar

Dmitry

Dmitry, 
Современные дети учатся включать компьютер быстрее,
чем начинают ходить.
Это полезно для развития системного и логического мышления.
Тем более,
это очень простые игры,
которые не сильно отличаются от обычных электронных игр, в которые играют дети.

www.youtube.com/watch?v=OnPXWwNVmLI&index=3&list=PLAHRa_lxEV7CmapCAH5N3TkNpck3F6TCI

А вот физику и математику маленькому ребенку еще рано
Максим Барбашин, физику — да, а арифметика — это раздел математики. Так что в самый раз. Ну вообще на вкус и цвет как говориться. Главное чтоб вам и вашему ребенку нравилось.
avatar

Dmitry

Dmitry, 
Просто если ребенок от природы эмоциональный,
программирование помогает научить его порядку, структурированию мыслей, разбивать задачу на этапы.
Есть стимул к изучению английского,
ребенок видит, что ему реально нужны знания.
И в той же математике.
Кроме того, есть социальный аспект.
Таким детям бывает сложно поддерживать коммуникации.
А тут он в своей среде, проще найти друзей.
Максим Барбашин, если ребенок эмоциональный, может ему лучше зайдут эмоциональные сферы? Танцы, музыка, литература, театр? Нет?
avatar

SergeyEgorov

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

Положительная обратная связь, короче. Главная чтобы была внутренняя мотивация и желание. Просто сидеть в школе без этого гораздо менее эффективно.
avatar

bstone

«Плюсануть» пока не могу. Ловите мой вербальный ПЛЮС!
avatar

Alex Boy

Автор идеи на хабре явно «перехимичил». id, code, названия инструментов лежат вот тут www.finam.ru/scripts/export.js практически в готовом виде. Т.е. парсить HTML вобще не нужно.
avatar

ivanovr

Спасибо. Хоть код и грязноват, идея рабочая. Только зачем скидывать в файл? Анализировать тоже в питоне например через pandas. Или хотите потом оффлайн работать с данными? И сдается мне что некоторые параметры необязательные — странно выглядит даты и тикер дважды. Попробуйте найти минимальный набор
avatar

Uncle Fedor

Uncle Fedor, такая строчка улетает на сервер финама, когда вы качаете котировки вручную. Это попытка воспроизвести её. 

… и дальше в этой строке СБЕР будет третий раз.
Albus (Игорь Китаев),
Советую освоить оператор %, с его помощью можно заменить
url = FINAM_URL + ticker+"_" + start_date_rev + "_" + end_date_rev + ".csv?" + params
url = ( 'http://export.finam.ru/%s_%s.csv?%s' % ( ticker,
start_date_rev,
end_date_rev, params ) )

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


avatar

tranquility

tranquility, спасибо. Освою :)
Uncle Fedor, сам pandas не пользовался, но мне кажется для новичка имело бы смысл сначала научиться пользоваться numpy, там для загрузки-выгрузки данных есть функции loadtxt и savetxt, этого в принципе достаточно. Ту же json структуру можно при необходимости реализовать при помощи списков и словарей. А потом уже когда научишься такое делать, можно и готовыми решениями воспользоваться, которые в том же pandas имеются.
avatar

tranquility

tranquility, скорее наооборот — лучше учить pandas. numpy нужно если вы реализуете достаточно сложные математические алгоритмы, в остальных случаях pandas и удобнее, и вполне достаточно. Pandas изначально написал человек, который работал в квант фонде AQR. Ну и padas.DataFrame имеет атрибут values, который хранит представление в виде массива numpy, если вдруг потребуется.
avatar

Михаил

главное не язык а сам алгоритм
avatar

autotrade.ru

а зачем всё это? 
avatar

HUKS

HUKS, для прогона вашей стратегии на исторических данных. 
Albus (Игорь Китаев), следующие посты будут посвящены написанию тестера стратегий написанных в qlua скриптах? ;)
avatar

tranquility

tranquility, хочу выпустить обновлённую версию этого робота.
smart-lab.ru/blog/458269.php
но не знаю что туда добавить.
Albus (Игорь Китаев), понятно. Сам что-то разочаровался в кластерном анализе, хотя кучу всего на С++ сделал для него. Но ничего, может, потом пригодится, как порой получается.
А я, наверное, как будет время, тут опубликую код для визуализации свечных графиков на питоне, в рамках, так сказать, питоновского просвещения общественности))
avatar

tranquility

Albus (Игорь Китаев), Эллиот все проверил)
avatar

HUKS

Albus (Игорь Китаев), ))))) так же я думал много лет назад))) пытался «прогнать… стратегию на исторических данных» Ха-ха-ха! Тогда мы использовали Metastock (он и сейчас стоит на одном из моих компьютеров). однако, все это, к сожалению для вас — не работает!) Особенно тогда, когда вы переходите к большим счетам — когда вы торгуете не 1-2 контрактами, а 1000-2000 контрактов (наример RTS) и более, тогда все эти стратегии, которые вы прогнали «на исторических данных» превращаются в пыль...)))
Я делал аналогичную задачу в Excel. Но примерно год назад все перестало работать, ибо вроде как финам рубанул всех сторонних. Теперь получается, все снова заработало. Надо бы проверить. 
avatar

Носорог

Носорог, год назад у него адрес сервера изменился. 
Носорог, у вас скорее всего этот сервер http://195.128.78.52
а надо новый: http://export.finam.ru/
Albus (Игорь Китаев), спасибо!
avatar

Носорог

Московский Лоссбой, под питон написано много скриптов, анализирующих опционы. Так что дело нужное. Питон тем и славится: работает медленно по сравнению с Си и Си++, но под него уже есть куча готового кода. Копипасти и работай.
Albus (Игорь Китаев), если пользоваться numpy (как раз касается обработки табличных данных), то разницу с С++ особо и не заметишь. Есть, но мизерная какая-то, причем не всегда в пользу последнего))
avatar

tranquility

Albus (Игорь Китаев), несколько дней на «каникулах» убил на аналогичную задачу! Где ж вы были, хотя бы на недельку раньше?))
Можете поделиться ссылками на скрипты, анализирующие опционы?
avatar

Сергей

Московский Лоссбой, в питоне все просто делается, главное начать. Если есть хоть какие-то навыки программирования, это несложно сделать будет. Потом кайфовать будете от осознания как легко реализовали то, на что потратили бы часы и дни делая это же на фортране. Для начала хотя бы установите питон себе и запустите этот скрипт Игоря, а дальше все само завертится, вот увидите!)
avatar

tranquility

Московский Лоссбой, 
Да справишься.
Есть книжки — раскраски для детей 7 лет.
Московский Лоссбой, 
Только не забудь приготовить цветные карандаши.
И резинку.
Московский Лоссбой, 
Резинка нужна, чтобы стирать!
А не то, о чем ты подумал.
Стоп.
А что ты планировал делать с карандашом?
Мой вариант — загрузка напрямую с биржи в асинхронном режиме https://github.com/WLM1ke/aiomoex
avatar

Михаил

Михаил, в разделе «открытие сессии» опечатка: «В конце работы для высвобождения ресурсов сессия должна быть закрыта вызовом метода closed.»
Исправить на close
avatar

ivanovr

ivanovr, исправил.
avatar

Михаил

Игорь, как поживает Ваш друг с которым вы одно время плотно пытались развить сайт торговых роботов? Вы с ним ещё дружите, или разсорились по политическим мотивам?
avatar

Aleks778

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

с помощью Jatotrader

Albus, а у тебя нет случайно идентификаторов всех финамовских эмитентов с ММВБ, которые используются для строки запроса:… txt?market=1&em=795&code=GMKN&a…
Дмитрий Иванов, идентификаторы всех акции есть внутри этого скрипта.
Albus (Игорь Китаев), В очередной раз спасибо за проделанную работу. Статья значительно ускорила решение аналогичной задачи!
avatar

Alex Boy

Albus (Игорь Китаев), еще раз спасибо — обновил свой макрос в Excel.

Возможно, пропущены:
473181 DSKY
491944 FIVE

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.

Залогиниться

Зарегистрироваться
....все тэги
UPDONW