├── bombier.pdf ├── opengosta.otf ├── bombier.tex ├── README.md ├── .gitignore ├── bom-gost.csv ├── bom.csv ├── cgroups.csv └── bombier.py /bombier.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dngulin/bombier/HEAD/bombier.pdf -------------------------------------------------------------------------------- /opengosta.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dngulin/bombier/HEAD/opengosta.otf -------------------------------------------------------------------------------- /bombier.tex: -------------------------------------------------------------------------------- 1 | \documentclass{xesel} 2 | 3 | \usepackage{polyglossia} 4 | \setdefaultlanguage{russian} 5 | \setotherlanguage{english} 6 | \defaultfontfeatures{Mapping=tex-text} 7 | \setmainfont[AutoFakeSlant=0.25,AutoFakeBold=0.2,Scale=0.8]{opengosta.otf} 8 | 9 | \usepackage{datatool} 10 | 11 | \begin{document} 12 | 13 | % BOMBIER configuration 14 | \XeselDesignedBy{Автор} 15 | % \XeselCheckedBy{} 16 | % \XeselInspectedBy{} 17 | % \XeselApprovedBy{} 18 | 19 | \XeselDocumentNumber{АБВГ 000000.001 ПЭ3} 20 | \XeselDocumentName{Устройство} 21 | \XeselOrganisation{ООО <<ЫЫЫ>>} 22 | 23 | \newcommand{\bomfile}{bom-gost.csv} 24 | 25 | 26 | \DTLloadrawdb[keys={Designator,Description,Count,Note}]{bom}{\bomfile} 27 | 28 | \begin{xesel} 29 | 30 | \DTLforeach{bom}{\Des=Designator, \Desc=Description, \Cnt=Count, \Note=Note}{% 31 | \ifthenelse{\equal{\Cnt}{}}{% 32 | \XeselHeader{\Desc} 33 | }{% 34 | \XeselEntry{\Des}{\Desc}{\Cnt}{\Note} 35 | } 36 | } 37 | 38 | \end{xesel} 39 | 40 | \end{document} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Bombier 2.0 2 | ===== 3 | 4 | Небольшой python-скрипт для генерации перечней элементов по ГОСТ из современных САПР с использованием XeLaTeX-класса XeSEL. 5 | 6 | Для того, чтобы получить готовый перечень в формате pdf необходимо получить из САПР csv-файл отсортированный по обозначению компонентов и содержащий следующие колонки данных (без группировки компонентов -- одна запись на один компонент): Designator, Footprint, Manufacturer, ComponentName, Value, Tolerance, ValueII, ValueIII, Note (колонки можно указать в начале скрипта) с названием bom.csv. Скрипт преобразует его в таблицу bom-gost.csv с 4 колонками, как в привычном ГОСТовском перечне элементов, после чего необходимо скомпилировать bombier.tex с помощью XeLaTeX. 7 | 8 | То, каким образом будут сгруппирвоаны компоненты, зависит от содержимого таблицы cgroups.csv. 9 | 10 | CSV таблицы должны быть кодированы в UTF-8, разделитель --- запятая, строки в двойных кавычках. 11 | 12 | Я использую скрипт в связке с Altium Designer, но его легко адаптировать и для других САПР. Кроме того, bom-gost.csv можно использовать не в связке с XeLaTeX, а скопировать его содержимое в электронную таблицу с нужным шаблоном. 13 | 14 | Для чего отдельно выделены ValueII и ValueIII? Для того, чтобы можно было отразить не схеме отдельно основное значение и дополнительное (например, емкость и допустимое напряжение конденсатора), а так же указать в свойствах компонента другие важные характеристики (например, ТКЕ или тип диэлектрика), которые должны попасть в перечень элементов. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Core latex/pdflatex auxiliary files: 2 | *.aux 3 | *.lof 4 | *.log 5 | *.lot 6 | *.fls 7 | *.out 8 | *.toc 9 | 10 | ## No latex classes 11 | *.cls 12 | 13 | ## Intermediate documents: 14 | *.dvi 15 | *-converted-to.* 16 | # these rules might exclude image files for figures etc. 17 | # *.ps 18 | # *.eps 19 | # *.pdf 20 | 21 | ## Bibliography auxiliary files (bibtex/biblatex/biber): 22 | *.bbl 23 | *.bcf 24 | *.blg 25 | *-blx.aux 26 | *-blx.bib 27 | *.brf 28 | *.run.xml 29 | 30 | ## Build tool auxiliary files: 31 | *.fdb_latexmk 32 | *.synctex.gz 33 | *.synctex.gz(busy) 34 | *.pdfsync 35 | 36 | ## Auxiliary and intermediate files from other packages: 37 | 38 | # algorithms 39 | *.alg 40 | *.loa 41 | 42 | # amsthm 43 | *.thm 44 | 45 | # beamer 46 | *.nav 47 | *.snm 48 | *.vrb 49 | 50 | #(e)ledmac/(e)ledpar 51 | *.end 52 | *.[1-9] 53 | *.[1-9][0-9] 54 | *.[1-9][0-9][0-9] 55 | *.[1-9]R 56 | *.[1-9][0-9]R 57 | *.[1-9][0-9][0-9]R 58 | *.eledsec[1-9] 59 | *.eledsec[1-9]R 60 | *.eledsec[1-9][0-9] 61 | *.eledsec[1-9][0-9]R 62 | *.eledsec[1-9][0-9][0-9] 63 | *.eledsec[1-9][0-9][0-9]R 64 | 65 | # glossaries 66 | *.acn 67 | *.acr 68 | *.glg 69 | *.glo 70 | *.gls 71 | 72 | # hyperref 73 | *.brf 74 | 75 | # listings 76 | *.lol 77 | 78 | # makeidx 79 | *.idx 80 | *.ilg 81 | *.ind 82 | *.ist 83 | 84 | # minitoc 85 | *.maf 86 | *.mtc 87 | *.mtc0 88 | 89 | # minted 90 | *.pyg 91 | 92 | # morewrites 93 | *.mw 94 | 95 | # nomencl 96 | *.nlo 97 | 98 | # sagetex 99 | *.sagetex.sage 100 | *.sagetex.py 101 | *.sagetex.scmd 102 | 103 | # sympy 104 | *.sout 105 | *.sympy 106 | sympy-plots-for-*.tex/ 107 | 108 | # todonotes 109 | *.tdo 110 | 111 | # xindy 112 | *.xdy 113 | -------------------------------------------------------------------------------- /bom-gost.csv: -------------------------------------------------------------------------------- 1 | Designator,Description,Count,Note 2 | ,,, 3 | ,Конденсаторы,, 4 | C1,"SMD C1210, Murata, 10 мкФ, 20%, 63 В, X5R",1, 5 | C2,"SMD C0603, Murata, 100 пФ, 20%, 6,3 В, X5R",1, 6 | C3,"HMD ECAP-12.5x30-AXIAL, Vishay, 150 мкФ, 20%, 63 В",1, 7 | C4,"SMD C0603, Murata, 1 нФ, 20%, 6,3 В, X5R",1, 8 | C5,"SMD C0603, Murata, 56 пФ, 20%, 6,3 В, X5R",1, 9 | C6...C8,"SMD C1210, Murata, 10 мкФ, 20%, 63 В, X5R",3, 10 | C9,"SMD C0603, Murata, 1 пФ, 20%, 6,3 В, X5R",1, 11 | C10,"SMD C1210, Murata, 10 мкФ, 20%, 63 В, X5R",1, 12 | C11,"SMD C0603, Murata, 30 пФ, 20%, 6,3 В, X5R",1, 13 | C12,"SMD C1210, Murata, 10 мкФ, 20%, 63 В, X5R",1, 14 | C13,"SMD C1210, Murata, 1 мкФ, 20%, 63 В, X5R",1, 15 | C14,"SMD C0805, Murata, 47 мкФ, 20%, 16 В, X5R",1, 16 | C15,"SMD C1210, Murata, 10 мкФ, 20%, 63 В, X5R",1, 17 | C16,"SMD C0805, Murata, 1 мкФ, 20%, 6,3 В, X5R",1, 18 | C17,"SMD C1210, Murata, 10 мкФ, 20%, 63 В, X5R",1, 19 | C18,"SMD C0805, Murata, 150 нФ, 20%, 16 В, X5R",1, 20 | C19...C24,"SMD C1210, Murata, 10 мкФ, 20%, 6,3 В, X5R",6, 21 | "C25, C26","SMD C1210, Murata, 100 мкФ, 20%, 6,3 В, X5R",2, 22 | ,,, 23 | DA1,"Микросхема SMD R-PVQFN-N20, Texas Instruments, TPS53219",1, 24 | ,,, 25 | ,Катушки индуктивности,, 26 | L1,"SMD WE-LHMI-1040, Wurth Electronics, 744373680022, 0,8 мкГн, 20%, 24 А, 800 мкОм",1, 27 | L2,"SMD B82559/020, Epcos, B82559A3152A020, 1 мкГн, 10%, 50 А, 900 мкОм",1, 28 | ,,, 29 | ,Резисторы,, 30 | R1,"SMD R0603, Yageo, 300 кОм, 5%, 0,1 Вт",1, 31 | R2,"SMD R0603, Yageo, 30 кОм, 5%, 0,1 Вт",1, 32 | R3,"SMD R0603, Yageo, 200 кОм, 1%, 0,1 Вт",1, 33 | R4,"SMD R0603, Yageo, 442 кОм, 1%, 0,1 Вт",1, 34 | R5,"SMD R0603, Yageo, 4,7 кОм, 5%, 0,1 Вт",1, 35 | R6,"SMD R0603, Yageo, 47 кОм, 5%, 0,1 Вт",1, 36 | R7,"SMD R0603, Yageo, 34 кОм, 1%, 0,1 Вт",1, 37 | R8,"SMD R0603, Yageo, 47 кОм, 5%, 0,1 Вт",1, 38 | R9,"SMD R0603, Yageo, 20 кОм, 1%, 0,1 Вт",1, 39 | R10,"SMD R0603, Yageo, 1,8 кОм, 5%, 0,1 Вт",1, 40 | R11,"SMD R0603, Yageo, 976 Ом, 1%, 0,1 Вт",1, 41 | R12,"SMD R0603, Yageo, 47 кОм, 5%, 0,1 Вт",1, 42 | R13,"SMD R0603, Yageo, 30 кОм, 5%, 0,1 Вт",1, 43 | R14,"SMD R0603, Yageo, 3,74 кОм, 1%, 0,1 Вт",1, 44 | R15,"SMD R0603, Yageo, 249 кОм, 1%, 0,1 Вт",1, 45 | "R16, R17","SMD R0603, Yageo, 10 кОм, 5%, 0,1 Вт",2, 46 | ,,, 47 | VD1,"Диод SMD MINIMELF-SOD80, Стабилитрон, 3,3 В",1, 48 | ,,, 49 | ,Транзисторы,, 50 | "VT1, VT2","SMD SOT-23/BT, NXP, BC817",2, 51 | VT3,"SMD TO-252/FET, Toshiba, TJ50S06M3L",1, 52 | VT4,"SMD SO8 5x6 UNI/FET, Texas Instruments, CSD18531Q5A",1, 53 | VT5,"SMD SO8 5x6 UNI/FET, Texas Instruments, CSD18532Q5B",1, 54 | VT6,"SMD SO8 5x6 UNI/FET, Texas Instruments, CSD18533Q5A",1, 55 | VT7,"SMD SO8 5x6 UNI/FET, Texas Instruments, CSD18534Q5A",1, 56 | -------------------------------------------------------------------------------- /bom.csv: -------------------------------------------------------------------------------- 1 | Designator,Footprint,Manufacturer,ComponentName,Value,Tolerance,ValueII,ValueIII,Note 2 | C1,SMD C1210,Murata,,10 мкФ,20%,63 В,X5R, 3 | C2,SMD C0603,Murata,,100 пФ,20%,"6,3 В",X5R, 4 | C3,HMD ECAP-12.5x30-AXIAL,Vishay,,150 мкФ,20%,63 В,, 5 | C4,SMD C0603,Murata,,1 нФ,20%,"6,3 В",X5R, 6 | C5,SMD C0603,Murata,,56 пФ,20%,"6,3 В",X5R, 7 | C6,SMD C1210,Murata,,10 мкФ,20%,63 В,X5R, 8 | C7,SMD C1210,Murata,,10 мкФ,20%,63 В,X5R, 9 | C8,SMD C1210,Murata,,10 мкФ,20%,63 В,X5R, 10 | C9,SMD C0603,Murata,,1 пФ,20%,"6,3 В",X5R, 11 | C10,SMD C1210,Murata,,10 мкФ,20%,63 В,X5R, 12 | C11,SMD C0603,Murata,,30 пФ,20%,"6,3 В",X5R, 13 | C12,SMD C1210,Murata,,10 мкФ,20%,63 В,X5R, 14 | C13,SMD C1210,Murata,,1 мкФ,20%,63 В,X5R, 15 | C14,SMD C0805,Murata,,47 мкФ,20%,16 В,X5R, 16 | C15,SMD C1210,Murata,,10 мкФ,20%,63 В,X5R, 17 | C16,SMD C0805,Murata,,1 мкФ,20%,"6,3 В",X5R, 18 | C17,SMD C1210,Murata,,10 мкФ,20%,63 В,X5R, 19 | C18,SMD C0805,Murata,,150 нФ,20%,16 В,X5R, 20 | C19,SMD C1210,Murata,,10 мкФ,20%,"6,3 В",X5R, 21 | C20,SMD C1210,Murata,,10 мкФ,20%,"6,3 В",X5R, 22 | C21,SMD C1210,Murata,,10 мкФ,20%,"6,3 В",X5R, 23 | C22,SMD C1210,Murata,,10 мкФ,20%,"6,3 В",X5R, 24 | C23,SMD C1210,Murata,,10 мкФ,20%,"6,3 В",X5R, 25 | C24,SMD C1210,Murata,,10 мкФ,20%,"6,3 В",X5R, 26 | C25,SMD C1210,Murata,,100 мкФ,20%,"6,3 В",X5R, 27 | C26,SMD C1210,Murata,,100 мкФ,20%,"6,3 В",X5R, 28 | DA1,SMD R-PVQFN-N20,Texas Instruments,TPS53219,,,,, 29 | L1,SMD WE-LHMI-1040,Wurth Electronics,744373680022,"0,8 мкГн",20%,24 А,800 мкОм, 30 | L2,SMD B82559/020,Epcos,B82559A3152A020,1 мкГн,10%,50 А,900 мкОм, 31 | R1,SMD R0603,Yageo,,300 кОм,5%,"0,1 Вт",, 32 | R2,SMD R0603,Yageo,,30 кОм,5%,"0,1 Вт",, 33 | R3,SMD R0603,Yageo,,200 кОм,1%,"0,1 Вт",, 34 | R4,SMD R0603,Yageo,,442 кОм,1%,"0,1 Вт",, 35 | R5,SMD R0603,Yageo,,"4,7 кОм",5%,"0,1 Вт",, 36 | R6,SMD R0603,Yageo,,47 кОм,5%,"0,1 Вт",, 37 | R7,SMD R0603,Yageo,,34 кОм,1%,"0,1 Вт",, 38 | R8,SMD R0603,Yageo,,47 кОм,5%,"0,1 Вт",, 39 | R9,SMD R0603,Yageo,,20 кОм,1%,"0,1 Вт",, 40 | R10,SMD R0603,Yageo,,"1,8 кОм",5%,"0,1 Вт",, 41 | R11,SMD R0603,Yageo,,976 Ом,1%,"0,1 Вт",, 42 | R12,SMD R0603,Yageo,,47 кОм,5%,"0,1 Вт",, 43 | R13,SMD R0603,Yageo,,30 кОм,5%,"0,1 Вт",, 44 | R14,SMD R0603,Yageo,,"3,74 кОм",1%,"0,1 Вт",, 45 | R15,SMD R0603,Yageo,,249 кОм,1%,"0,1 Вт",, 46 | R16,SMD R0603,Yageo,,10 кОм,5%,"0,1 Вт",, 47 | R17,SMD R0603,Yageo,,10 кОм,5%,"0,1 Вт",, 48 | VD1,SMD MINIMELF-SOD80,,Стабилитрон,"3,3 В",,,, 49 | VT1,SMD SOT-23/BT,NXP,BC817,,,,, 50 | VT2,SMD SOT-23/BT,NXP,BC817,,,,, 51 | VT3,SMD TO-252/FET,Toshiba,TJ50S06M3L,,,,, 52 | VT4,SMD SO8 5x6 UNI/FET,Texas Instruments,CSD18531Q5A,,,,, 53 | VT5,SMD SO8 5x6 UNI/FET,Texas Instruments,CSD18532Q5B,,,,, 54 | VT6,SMD SO8 5x6 UNI/FET,Texas Instruments,CSD18533Q5A,,,,, 55 | VT7,SMD SO8 5x6 UNI/FET,Texas Instruments,CSD18534Q5A,,,,, 56 | -------------------------------------------------------------------------------- /cgroups.csv: -------------------------------------------------------------------------------- 1 | Base,Single,Multiple 2 | A,Устройство,Устройства 3 | B,Преобразователь,Преобразователи неэлектрических величин 4 | BA,Громкоговоритель,Преобразователи неэлектрических величин 5 | BB,Магнитострикционный элемент,Преобразователи неэлектрических величин 6 | BD,Детектор ионизирующего излучения,Преобразователи неэлектрических величин 7 | BE,Сельсин-приемник,Преобразователи неэлектрических величин 8 | BF,Телефон,Преобразователи неэлектрических величин 9 | BC,Сельсин-датчик,Преобразователи неэлектрических величин 10 | BK,Тепловой датчик,Преобразователи неэлектрических величин 11 | BL,Фотоэлемент,Преобразователи неэлектрических величин 12 | BM,Микрофон,Преобразователи неэлектрических величин 13 | BP,Датчик давления,Преобразователи неэлектрических величин 14 | BQ,Пьезоэлемент,Преобразователи неэлектрических величин 15 | BR,Датчик частоты вращения,Преобразователи неэлектрических величин 16 | BS,Звукосниматель,Преобразователи неэлектрических величин 17 | BV,Датчик скорости,Преобразователи неэлектрических величин 18 | C,Конденсатор,Конденсаторы 19 | D,Микросхема,Микросхемы 20 | DA,Микросхема,Микросхемы 21 | DD,Микросхема,Микросхемы 22 | DS,Устройство хранения информации,Микросхемы 23 | DT,Устройство задержки,Микросхемы 24 | E,Элемент,Элементы разные 25 | EK,Нагревательный элемент,Элементы разные 26 | EL,Лампа осветительная,Элементы разные 27 | ET,Пиропатрон,Элементы разные 28 | F,Устройство защитное,Устройства защитные 29 | FA,Элемент защиты по току,Устройства защитные 30 | FP,Элемент защиты по току инерционного действия,Устройства защитные 31 | FU,Предохранитель плавкий,Устройства защитные 32 | FV,Элемент защиты по напряжению,Устройства защитные 33 | G,Генератор,"Генераторы, источники питания" 34 | GB,Батарея,"Генераторы, источники питания" 35 | H,Устройство сигнальное,Устройства сигнальные 36 | HA,Прибор звуковой сигнализации,Устройства сигнальные 37 | HG,Индикатор символьный,Устройства сигнальные 38 | HL,Прибор световой сигнализации,Устройства сигнальные 39 | K,Реле,Реле 40 | KA,Реле токовое,Реле 41 | KH,Реле указательное,Реле 42 | KK,Реле электротепловое,Реле 43 | KM,Контактор,Реле 44 | KT,Реле времени,Реле 45 | KV,Реле напряжения,Реле 46 | L,Катушка индуктивности,Катушки индуктивности 47 | LL,Дроссель люминесцентного освещения,Катушки индуктивности 48 | M,Двигатель,Двигатели 49 | P,Прибор измерительный,Приборы измерительные 50 | PA,Амперметр,Приборы измерительные 51 | PC,Счётчик импульсов,Приборы измерительные 52 | PF,Частотомер,Приборы измерительные 53 | PI,Счетчик активной энергии,Приборы измерительные 54 | PK,Счетчик реактивной энергии,Приборы измерительные 55 | PR,Омметр,Приборы измерительные 56 | PS,Регистрирующий прибор,Приборы измерительные 57 | PT,Измеритель времени,Приборы измерительные 58 | PV,Вольтметр,Приборы измерительные 59 | PW,Ваттметр,Приборы измерительные 60 | Q,Переключатель силовой,Переключатели силовые 61 | QF,Выключатель автоматический,Переключатели силовые 62 | QK,Короткозамыкатель,Переключатели силовые 63 | QS,Разъединитель,Переключатели силовые 64 | R,Резистор,Резисторы 65 | RK,Терморезистор,Резисторы 66 | RP,Потенциометр,Резисторы 67 | RS,Шунт измерительный,Резисторы 68 | RU,Варистор,Резисторы 69 | S,Устройство коммутационное,Устройства коммутационные 70 | SB,Выключатель кнопочный,Устройства коммутационные 71 | SF,Выключатель автоматический,Устройства коммутационные 72 | SL,Выключатель по уровню,Устройства коммутационные 73 | SP,Выключатель по давлению,Устройства коммутационные 74 | SQ,Выключатель по положению,Устройства коммутационные 75 | SR,Выключатель по частоте вращения,Устройства коммутационные 76 | SK,Выключатель по температуре,Устройства коммутационные 77 | T,Трансформатор,Трансформаторы 78 | TA,Трансформатор тока,Трансформаторы 79 | TS,Электромагнитный стабилизатор,Трансформаторы 80 | TV,Трансформатор напряжения,Трансформаторы 81 | U,Преобразователь электрических величин,Преобразователи электрических величин 82 | UB,Модулятор,Преобразователи электрических величин 83 | UR,Демодулятор,Преобразователи электрических величин 84 | UI,Дискриминатор,Преобразователи электрических величин 85 | UZ,Преобразователь частотный,Преобразователи электрических величин 86 | V,Прибор,Приборы 87 | VD,Диод,Диоды 88 | VL,Прибор электровакуумный,Лампы 89 | VT,Транзистор,Транзисторы 90 | VS,Тиристор,Тиристоры 91 | W,Элемент СВЧ,Элементы СВЧ 92 | WE,Ответвитель,Элементы СВЧ 93 | WK,Короткозамыкатель,Элементы СВЧ 94 | WS,Вентиль,Элементы СВЧ 95 | WT,Трансформатор,Элементы СВЧ 96 | WU,Аттенюатор,Элементы СВЧ 97 | WA,Антенна,Элементы СВЧ 98 | X,Соединитель,Соединители 99 | XA,Токосъемник,Соединители 100 | XP,Штырь,Соединители 101 | XS,Гнездо,Соединители 102 | XT,Соединение разборное,Соединители 103 | XW,Соединитель высокочастотный,Соединители 104 | Y,Устройство с электромагнитным приводом,Устройства с электромагнитным приводом 105 | YA,Электромагнит,Устройства с электромагнитным приводом 106 | YB,Тормоз с электромагнитным приводом,Устройства с электромагнитным приводом 107 | YC,Муфта с электромагнитным приводом,Устройства с электромагнитным приводом 108 | YH,Электромагнитный патрон,Устройства с электромагнитным приводом 109 | Z,Оконечный фильтр,Фильтры 110 | ZL,Ограничитель,Фильтры 111 | ZQ,Фильтр кварцевый,Фильтры 112 | -------------------------------------------------------------------------------- /bombier.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | # Bombier GOST script v2.0 4 | 5 | import csv 6 | 7 | # 8 | # Configurations 9 | # 10 | 11 | # Input and output filenames 12 | inBomName = 'bom.csv' 13 | outBomName = 'bom-gost.csv' 14 | 15 | # Corresponding between BOM and Gost-BOM CSV columns 16 | gostDesColumn = 'Designator' 17 | gostCompColumn = ['Footprint','Manufacturer','ComponentName','Value','Tolerance','ValueII','ValueIII'] 18 | gostNoteColumn = 'Note' 19 | 20 | 21 | # 22 | # Functions 23 | # 24 | 25 | # Get base of designator (R for R12, C for C2, etc) 26 | def base(designator): 27 | return ''.join([i for i in designator if not i.isdigit()]) 28 | 29 | # Add comma before string if not empty 30 | def commatize(string): 31 | if string == '': 32 | return '' 33 | else: 34 | return ', ' + string 35 | 36 | # Make component description column 37 | def mkdesc(rawEntry, columns): 38 | desc = rawEntry[columns[0]] 39 | for field in columns[1:]: 40 | desc = desc + commatize(rawEntry[field]) 41 | return desc 42 | 43 | # Make designator cell content for GOST bom 44 | def mkdes(first, last, count): 45 | if count == 1: 46 | return first 47 | elif count == 2: 48 | return first + ', ' + last 49 | else: 50 | return first + '...' + last 51 | 52 | 53 | # 54 | # First conversion pass to temp BOM (without group headers) 55 | # 56 | 57 | # Define BOM-conversion structure 58 | class Entry: 59 | pass 60 | 61 | convBomEntry = Entry() # Conversion BOM entry (maked from input BOM) 62 | tempBomEntry = Entry() # Temp BOM entry 63 | 64 | convBomEntry.desBase = '' # Designator base (R for R12, C for C2, etc) 65 | convBomEntry.compDesc = '' # Component description 66 | convBomEntry.compNote = '' # Component note 67 | 68 | tempBomEntry.desBase = '' # Designator base (R for R12, C for C2, etc) 69 | tempBomEntry.desFirst = '' # First designator in entry 70 | tempBomEntry.desLast = '' # Last designator in entry 71 | tempBomEntry.compDesc = '' # Component description 72 | tempBomEntry.compCount = 0 # Component count 73 | tempBomEntry.compNote = '' # Component note 74 | 75 | # Temporary BOM. Fields: 'Designator', 'Description', 'Count', 'Note', 'Base' 76 | # 'Base' field needed for second conversion pass 77 | tempbom = [] 78 | 79 | # Reading input BOM csv 80 | with open(inBomName, 'r', encoding='utf-8') as bomcsv: 81 | bomreader = csv.DictReader(bomcsv, delimiter=',', quotechar='"') 82 | 83 | for rawEntry in bomreader: 84 | # Begin fill tempBomEntry if empty 85 | if tempBomEntry.compCount == 0: 86 | tempBomEntry.desBase = base(rawEntry[gostDesColumn]) 87 | tempBomEntry.desFirst = rawEntry[gostDesColumn] 88 | tempBomEntry.desLast = rawEntry[gostDesColumn] 89 | tempBomEntry.compDesc = mkdesc(rawEntry, gostCompColumn) 90 | tempBomEntry.compCount = 1 91 | tempBomEntry.compNote = rawEntry[gostNoteColumn] 92 | else: 93 | # Fill conversion structure 94 | convBomEntry.desBase = base(rawEntry[gostDesColumn]) 95 | convBomEntry.compDesc = mkdesc(rawEntry, gostCompColumn) 96 | convBomEntry.compNote = rawEntry[gostNoteColumn] 97 | 98 | # Update temp entry if data similar 99 | if (convBomEntry.desBase + convBomEntry.compDesc + convBomEntry.compNote) == \ 100 | (tempBomEntry.desBase + tempBomEntry.compDesc + tempBomEntry.compNote): 101 | tempBomEntry.desLast = rawEntry[gostDesColumn] 102 | tempBomEntry.compCount = tempBomEntry.compCount + 1 103 | else: 104 | # Move tempBomEntry to tempbom 105 | tempbom.append({'Designator': mkdes(tempBomEntry.desFirst, 106 | tempBomEntry.desLast, 107 | tempBomEntry.compCount), 108 | 'Description': tempBomEntry.compDesc, 109 | 'Count': tempBomEntry.compCount, 110 | 'Note': tempBomEntry.compNote, 111 | 'Base': tempBomEntry.desBase}) 112 | 113 | # Begin fill next tempBomEntry 114 | tempBomEntry.desBase = base(rawEntry[gostDesColumn]) 115 | tempBomEntry.desFirst = rawEntry[gostDesColumn] 116 | tempBomEntry.desLast = rawEntry[gostDesColumn] 117 | tempBomEntry.compDesc = mkdesc(rawEntry, gostCompColumn) 118 | tempBomEntry.compCount = 1 119 | tempBomEntry.compNote = rawEntry[gostNoteColumn] 120 | 121 | # Move last tempBomEntry to tempbom 122 | tempbom.append({'Designator': mkdes(tempBomEntry.desFirst, 123 | tempBomEntry.desLast, 124 | tempBomEntry.compCount), 125 | 'Description': tempBomEntry.compDesc, 126 | 'Count': tempBomEntry.compCount, 127 | 'Note': tempBomEntry.compNote, 128 | 'Base': tempBomEntry.desBase}) 129 | 130 | # 131 | # Second conversion pass to output BOM 132 | # 133 | 134 | # Read BOM headers before conversion 135 | # cgroups fields: 'Base', 'Single', 'Multiple' 136 | cgroups = [] 137 | 138 | with open('cgroups.csv', 'r', encoding='utf-8') as cgcsv: 139 | cgreader = csv.DictReader(cgcsv, delimiter=',', quotechar='"') 140 | for entry in cgreader: 141 | cgroups.append(entry) 142 | 143 | # Output BOM generation data 144 | 145 | outbom = [] # Output BOM 146 | lastgroup = [] # Last component group 147 | singletitle = '' # Last group titles 148 | multititle = '' 149 | 150 | 151 | # Second pass functions 152 | 153 | def getsingle(base, cgroups): 154 | for entry in cgroups: 155 | if entry['Base'] == base: 156 | return entry['Single'] 157 | return "Неизвестный компонент" 158 | 159 | def getmulti(base, cgroups): 160 | for entry in cgroups: 161 | if entry['Base'] == base: 162 | return entry['Multiple'] 163 | return "Неизвестные компоненты" 164 | 165 | def outputgroup(outbom, lastgroup): 166 | if len(lastgroup) == 1: 167 | outbom.append({'Designator': '', 168 | 'Description': '', 169 | 'Count': '', 170 | 'Note': ''}) 171 | outbom.append({'Designator': lastgroup[0]['Designator'], 172 | 'Description': singletitle + ' ' + lastgroup[0]['Description'], 173 | 'Count': lastgroup[0]['Count'], 174 | 'Note': lastgroup[0]['Note']}) 175 | else: 176 | outbom.append({'Designator': '', 177 | 'Description': '', 178 | 'Count': '', 179 | 'Note': ''}) 180 | outbom.append({'Designator': '', 181 | 'Description': multititle, 182 | 'Count': '', 183 | 'Note': ''}) 184 | for row in lastgroup: 185 | outbom.append({'Designator': row['Designator'], 186 | 'Description': row['Description'], 187 | 'Count': row['Count'], 188 | 'Note': row['Note']}) 189 | 190 | # Output BOM generation 191 | 192 | for entry in tempbom: 193 | # First iteration 194 | if multititle == '': 195 | lastgroup.append({'Designator': entry['Designator'], 196 | 'Description': entry['Description'], 197 | 'Count': entry['Count'], 198 | 'Note': entry['Note']}) 199 | singletitle = getsingle(entry['Base'], cgroups) 200 | multititle = getmulti(entry['Base'], cgroups) 201 | # Extend group 202 | elif getmulti(entry['Base'], cgroups) == multititle: 203 | lastgroup.append({'Designator': entry['Designator'], 204 | 'Description': entry['Description'], 205 | 'Count': entry['Count'], 206 | 'Note': entry['Note']}) 207 | # Output group, make new group 208 | else: 209 | # Output group 210 | outputgroup(outbom, lastgroup) 211 | 212 | # Flush and fill group 213 | lastgroup = [] 214 | lastgroup.append({'Designator': entry['Designator'], 215 | 'Description': entry['Description'], 216 | 'Count': entry['Count'], 217 | 'Note': entry['Note']}) 218 | singletitle = getsingle(entry['Base'], cgroups) 219 | multititle = getmulti(entry['Base'], cgroups) 220 | # Output group 221 | outputgroup(outbom, lastgroup) 222 | 223 | # Print result 224 | for entry in outbom: 225 | print(entry['Designator'], '\t', 226 | entry['Description'], '\t', 227 | entry['Count'], '\t', 228 | entry['Note']) 229 | 230 | # Write output BOM 231 | with open(outBomName, 'w', encoding='utf-8', newline='') as gostbomcsv: 232 | fieldnames = ['Designator', 'Description', 'Count', 'Note'] 233 | writer = csv.DictWriter(gostbomcsv, fieldnames=fieldnames) 234 | 235 | writer.writeheader() 236 | for entry in outbom: 237 | writer.writerow({'Designator': entry['Designator'], 238 | 'Description': entry['Description'], 239 | 'Count': entry['Count'], 240 | 'Note': entry['Note']}) 241 | 242 | 243 | --------------------------------------------------------------------------------