找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 20201|回复: 2

[原创] 学习vbs后的练习代码

[复制链接]
发表于 2013-8-4 07:31:24 | 显示全部楼层 |阅读模式
前段时间学习了vbs,我的习惯是学习一门新的语言之后,得想方设法用它完成一个比较困难的任务,于是写了一个工作中可以用到的脚本,已经在部门内分发,反响不错。代码没什么通用性,大致是完成一些Excel表格的制作和文本文件与Excel的比对,与工作相关了。贴出来的目的,有作秀的成分,也有与vbs同学共勉的成分,最想的还是鼓励大家写一些较大型的程序,这样我们会接触到更多关于代码规范性和结构化的东西。本人仅菜鸟一枚,不必膜拜。

  1. option explicit
  2. 'On Error Resume Next
  3. dim strPrompt                     'function table string
  4. dim intFunction                                'holds user's choice
  5. dim strChoices                                'characters user can enter
  6. dim objShell                                'WScript shell object
  7. dim fso                                                'File system object
  8. dim setupfile                                'setup file for this script
  9. const ForReading=1                        'ForWriting=2, ForAppending=8
  10. dim i,item                                        'variables to walk through an array or loop

  11. strPrompt="Choose a function from the table:" & vbNewLine &vbNewLine &_
  12.                         "1. Generate CIS Pre-BOM." & vbNewLine &_
  13.                         "2. Compare CIS and PDM BOMs." & vbNewLine &_
  14.                         "3. Generate HDL Pre-BOM." & vbNewLine &_
  15.                         "4. Compare HDL and PDM BOMs." & vbNewLine &_
  16.                         "5. Compare two PDM BOMs." & vbNewLine
  17. strChoices="12345"
  18. set objShell=CreateObject("WScript.Shell")
  19. set fso=CreateObject("scripting.FileSystemObject")
  20. setupfile=objShell.CurrentDirectory & "\setup.ini"

  21. 'function table
  22. do
  23.         intFunction=InputBox(strPrompt,"Function Table",1)
  24.         if intFunction="" then WScript.Quit
  25. loop until InStr(strChoices,Left(intFunction,1))
  26. select case CInt(Left(intFunction,1))
  27.         case 1
  28.                 call preBOM(1)
  29.         case 2
  30.                 call Compare(1)
  31.         case 3
  32.                 call preBOM(2)
  33.         case 4
  34.                 call Compare(2)
  35.         case 5
  36.                 call Compare(3)
  37.         case else
  38.                 MsgBox "Runtime error, program will exit.", _
  39.                                 vbOKOnly+vbExclamation,"error"
  40.                 WScript.Quit
  41. end select


  42. '****************function and subroutine area***************
  43. 'sub to read text bom file to generate pre-Bom
  44. 'CISorHDL identify the type of the text BOM, 1=CIS and 2=HDL
  45. sub preBOM(CISorHDL)
  46.         dim StartLine,PartNumber,Quantity, _
  47.                 IsPOP,NPOP,HeaderLine,Location, _
  48.                 SmdPN,DipPN,PcbPN                                                'values read from setup.ini
  49.         dim dictSetup                                                                'dictionary holding setup information
  50.         dim arrCheckSetup                                                        'holds all needed setup strings
  51.         dim bomFile                                 'points to the bom file
  52.         dim dictParts                                                                'dictionary holds all parts, keys are part numbers
  53.                                                                                                 'and items are class part objects
  54.         dim strBegin                                                                'identify the beginning of information scope
  55.         dim strEnd                                                                        'idenfity the end of information scope
  56.        
  57.         'veriry preBOM type
  58.         if CISorHDL=1 then
  59.                 strBegin="<CIS_preBOM>"
  60.                 strEnd="</CIS_preBOM>"
  61.         elseif CISorHDL=2 then
  62.                 strBegin="<HDL_preBOM>"
  63.                 strEnd="</HDL_preBOM>"
  64.         end if
  65.        
  66.         'check if all necessary information is aquired from setup.ini
  67.         arrCheckSetup=Array("StartLine","PartNumber","Quantity","IsPOP", _
  68.                 "Location","NPOP","HeaderLine","SmdPN","DipPN","PcbPN")
  69.         set dictSetup=ReadSetup(setupfile,strBegin,strEnd)
  70.         for each item in arrCheckSetup
  71.                 if not dictSetup.Exists(item) then
  72.                         MsgBox "No """ & item & """ value found in " &_
  73.                                 setupfile & ", please check your file.", _
  74.                                 vbOkOnly+vbCritical,"Error"
  75.                 end if
  76.                 Execute(item & "=dictSetup.item(""" & item & """)")
  77.         next
  78.        
  79.         'let user choose bom file
  80.         'if user clicks CANCEL, program exists
  81.         bomFile=BrowseForFile()
  82.         if bomFile="" then
  83.                 WScript.Quit
  84.         end if
  85.        
  86.         'begin to read parts
  87.         set dictParts=CreateObject("scripting.Dictionary")
  88.         set dictParts=ReadTextParts(bomFile,HeaderLine,StartLine,PartNumber,Quantity,IsPOP,Location,NPOP,",")
  89.        
  90.         'write part dictionary to Excel
  91.         call WriteToExcel(dictParts,SmdPN,DipPN,PcbPN)
  92. end sub

  93. 'sub to compare text bom file with excel bom or two excel boms
  94. 'CompareType identify the comparision, 1=CIS_PDM and 2=HDL_PDM and 3=twoPDM
  95. sub Compare(CompareType)
  96.         dim StartLine,PartNumber,Quantity, _
  97.                 IsPOP,NPOP,HeaderLine,Location,ExcelHeaderLine, _
  98.                 ExcelStartLine,ExcelPartNumber,_
  99.                 ParentPN,ExcelQuantity,        _
  100.                 ExcelLocation,ExcelLevel                                'values read from setup.ini
  101.         dim dictSetup                                                                'dictionary holding setup information
  102.         dim arrCheckSetup                                                        'holds all needed setup strings
  103.         dim FirstFile                               'points to the first bom file
  104.         dim SecondFile                                                                'points to the second bom file
  105.         dim dictFirstParts                                                        'dictionary holds the first part dictionary
  106.         dim dictSecondParts                                                        'dictionary holds the first part dictionary
  107.                                                                                                 'and items are class part objects
  108.         dim strBegin                                                                'identify the beginning of information scope
  109.         dim strEnd                                                                        'idenfity the end of information scope
  110.         dim strPrompt                                                                'string shown on MsgBox or InputBox
  111.        
  112.         'veriry preBOM type
  113.         if CompareType=1 then
  114.                 strBegin="<CIS_PDM>"
  115.                 strEnd="</CIS_PDM>"
  116.                 arrCheckSetup=Array("StartLine","PartNumber","Quantity","IsPOP", _
  117.                 "Location","NPOP","HeaderLine","ExcelHeaderLine", _
  118.                 "ExcelStartLine","ExcelPartNumber","ParentPN","ExcelQuantity",        _
  119.                 "ExcelLocation","ExcelLevel")
  120.         elseif CompareType=2 then
  121.                 strBegin="<HDL_PDM>"
  122.                 strEnd="</HDL_PDM>"
  123.                 arrCheckSetup=Array("StartLine","PartNumber","Quantity","IsPOP", _
  124.                 "Location","NPOP","HeaderLine","ExcelHeaderLine", _
  125.                 "ExcelStartLine","ExcelPartNumber","ParentPN","ExcelQuantity",        _
  126.                 "ExcelLocation","ExcelLevel")
  127.         elseif CompareType=3 then
  128.                 strBegin="<twoPDM>"
  129.                 strEnd="</twoPDM>"
  130.                 arrCheckSetup=Array("ExcelHeaderLine", _
  131.                 "ExcelStartLine","ExcelPartNumber","ParentPN","ExcelQuantity",        _
  132.                 "ExcelLocation","ExcelLevel")
  133.         else
  134.                 Err.Raise 104,"BomKit check error.","BomKit doesn't support this kind of comparison: " & CompareType
  135.         end if
  136.        
  137.         'check if all necessary information is aquired from setup.ini
  138.         set dictSetup=ReadSetup(setupfile,strBegin,strEnd)
  139.         for each item in arrCheckSetup
  140.                 if not dictSetup.Exists(item) then
  141.                         MsgBox "No """ & item & """ value found in " &_
  142.                                 setupfile & ", please check your file.", _
  143.                                 vbOkOnly+vbCritical,"Error"
  144.                 end if
  145.                 Execute(item & "=dictSetup.item(""" & item & """)")
  146.         next
  147.        
  148.         'let user choose 2 bom files
  149.         'if user clicks CANCEL, program exists
  150.         select case CompareType
  151.                 case 1
  152.                         strPrompt="You are going to choose the BOM file generated by Allegro CIS."
  153.                 case 2
  154.                         strPrompt="You are going to choose the BOM file generated by Allegro HDL."
  155.                 case 3
  156.                         strPrompt="You are going to choose the excel file downloaded from PDM."
  157.         end select
  158.         MsgBox strPrompt,vbInformation,"Note"
  159.         FirstFile=BrowseForFile()
  160.         if FirstFile="" then
  161.                 WScript.Quit
  162.         end if
  163.         'begin to read first bom
  164.         set dictFirstParts=CreateObject("scripting.Dictionary")
  165.         set dictSecondParts=CreateObject("scripting.Dictionary")
  166.         if CompareType=1 or CompareType=2 then
  167.                 set dictFirstParts=ReadTextParts(FirstFile,HeaderLine,StartLine,PartNumber,Quantity,IsPOP,Location,NPOP,",")
  168.         else
  169.                 set dictFirstParts=ReadExcelParts(FirstFile,ExcelHeaderLine,ExcelStartLine,ExcelPartNumber, _
  170.                         ParentPN,ExcelQuantity,ExcelLocation,ExcelLevel)
  171.         end if
  172.        
  173.         strPrompt="You are going to choose the excel file downloaded from PDM."
  174.         MsgBox strPrompt,vbInformation,"Note"
  175.         SecondFile=BrowseForFile()
  176.         if SecondFile="" then
  177.                 WScript.Quit
  178.         end if
  179.         'begin to read second bom
  180.         set dictSecondParts=ReadExcelParts(SecondFile,ExcelHeaderLine,ExcelStartLine,ExcelPartNumber, _
  181.                         ParentPN,ExcelQuantity,ExcelLocation,ExcelLevel)
  182.         'begin to compare the two dictionaries
  183.         dim arrCompare
  184.         arrCompare=CompareDicts(dictFirstParts,dictSecondParts)
  185.        
  186.         dim fso,objTextStream,objShell,re
  187.         set re=new RegExp
  188.         re.Pattern="[\n\r]+$"
  189.         set fso=CreateObject("scripting.FileSystemObject")
  190.         set objShell=CreateObject("WScript.Shell")
  191.         set objTextStream=fso.OpenTextFile(objShell.CurrentDirectory & "\compare.txt",2,true)
  192.         objTextStream.WriteLine "Comparision results generated by BomKit"
  193.         objTextStream.WriteLine Date & " " & Time & vbNewLine
  194.         objTextStream.WriteLine "Below items exist only in " & FirstFile & vbNewLine & String(80,"=")
  195.         objTextStream.Write re.Replace(arrCompare(0),"") & vbNewLine & String(80,"=") & vbNewLine & vbNewLine & vbNewLine
  196.         objTextStream.WriteLine "Below items exist only in " & SecondFile & vbNewLine & String(80,"=")
  197.         objTextStream.Write re.Replace(arrCompare(1),"") & vbNewLine & String(80,"=") & vbNewLine & vbNewLine & vbNewLine
  198.         objTextStream.WriteLine "Below are mismatched items" & vbNewLine & String(80,"=")
  199.         objTextStream.Write re.Replace(arrCompare(2),"") & vbNewLine & String(80,"=") & vbNewLine & vbNewLine & vbNewLine
  200.         objTextStream.Close
  201.         objShell.Run(objShell.CurrentDirectory & "\compare.txt")
  202. end sub

  203. 'function to let user choose a file
  204. function BrowseForFile()
  205.     dim shell : set shell = CreateObject("WScript.Shell")
  206.     dim fso : set fso = CreateObject("Scripting.FileSystemObject")
  207.     dim tempFolder : set tempFolder = fso.GetSpecialFolder(2)
  208.     dim tempName : tempName = fso.GetTempName()
  209.     dim tempFile : set tempFile = tempFolder.CreateTextFile(tempName & ".hta")
  210.     tempFile.Write _
  211.     "<html>" & _
  212.     "<head>" & _
  213.     "<title>Browse</title>" & _
  214.     "</head>" & _
  215.     "<body>" & _
  216.     "<input type='file' id='f' />" & _
  217.     "<script type='text/javascript'>" & _
  218.     "var f = document.getElementById('f');" & _
  219.     "f.click();" & _
  220.     "var shell = new ActiveXObject('WScript.Shell');" & _
  221.     "shell.RegWrite('HKEY_CURRENT_USER\\Volatile Environment\\MsgResp', f.value);" & _
  222.     "window.close();" & _
  223.     "</script>" & _
  224.     "</body>" & _
  225.     "</html>"
  226.     tempFile.Close
  227.     shell.Run tempFolder & "" & tempName & ".hta", 0, true
  228.     BrowseForFile = shell.RegRead("HKEY_CURRENT_USER\Volatile Environment\MsgResp")
  229.     shell.RegDelete "HKEY_CURRENT_USER\Volatile Environment\MsgResp"
  230. end function

  231. 'read configuration information from the file specified by strSetupfile
  232. 'strBegin and strEnd identify the information scope
  233. 'returns a dictionary containing configuration information
  234. function ReadSetup(strSetupfile,strBegin,strEnd)
  235.         dim objTextStream,strLine,IsReading,fso    'For reading setup file
  236.         const ForReading=1                                                      'ForWriting=2, ForAppending=8
  237.         dim re                                                                       'regular expression
  238.         dim dictSetup,arrLine                                           'dictionary holding setup information
  239.        
  240.         set fso=CreateObject("scripting.FileSystemObject")
  241.         set objTextStream=fso.OpenTextFile(strSetupfile,ForReading,false,-2)
  242.         set dictSetup=CreateObject("scripting.Dictionary")
  243.         IsReading=false
  244.         strLine=Empty
  245.         set re=new RegExp
  246.         re.Pattern="=([^\t]+)\t+'.*$"
  247.         do
  248.                 strLine=objTextStream.ReadLine
  249.                 if UCase(strLine)=UCase(strEnd) then IsReading=false
  250.                 if IsReading then
  251.                         strLine=re.Replace(strLine,"=$1")
  252.                         arrLine=split(strLine,"=")
  253.                         dictSetup.Add arrLine(0),arrLine(1)
  254.                 end if
  255.                 if UCase(strLine)=UCase(strBegin) then IsReading=true
  256.         loop until strLine=strEnd or objTextStream.AtEndOfStream
  257.         objTextStream.Close
  258.         set ReadSetup=dictSetup
  259. end function

  260. 'sub to write specific information to setup.ini
  261. 'strBegin and strEnd identify the information scope
  262. 'strKey and strValue identify where and what
  263. sub WriteSetup(strSetupfile,strBegin,strEnd,strKey,strValue)
  264.         dim objTextStream,strLine,IsReading,arrLine,fso,item
  265.         const ForReading=1,ForWriting=2
  266.         dim re
  267.        
  268.         set fso=CreateObject("scripting.FileSystemObject")
  269.         set objTextStream=fso.OpenTextFile(strSetupFile,ForReading,false,-2)
  270.         strLine=objTextStream.ReadAll
  271.         objTextStream.Close
  272.         arrLine=Split(strLine,vbNewLine)
  273.         set objTextStream=fso.OpenTextFile(strSetupFile,ForWriting)
  274.         IsReading=false
  275.         set re=new RegExp
  276.         re.Pattern="^" & strKey & "=[^\t]*(\t+'.*$)"
  277.         re.IgnoreCase=true
  278.         for each item in arrLine
  279.                 strLine=item
  280.                 if UCase(item)=UCase(strEnd) then IsReading=false
  281.                 if IsReading and UCase(Left(strLine,Len(strKey)))=UCase(strKey) then
  282.                         strLine=re.Replace(strLine,strKey & "=" & strValue & "$1")
  283.                 end if
  284.                 if UCase(item)=UCase(strBegin) then IsReading=true
  285.                 objTextStream.WriteLine strLine
  286.         next
  287.         objTextStream.Close
  288. end sub

  289. 'function to read parts to a dictionary from the file specified by strFile
  290. 'HeaderLine identifies the header line number
  291. 'StartLine identifies the first line to start to read
  292. 'dictColumn contains column numbers of PartNumber,Quantity,IsPOP,Location
  293. 'PartNumber,Quantity,IsPOP,Location refers to column names
  294. 'strNPOP contains those values make a part NPOP
  295. 'chrSepar specifies location separator
  296. function ReadTextParts(strFile,HeaderLine,StartLine,PartNumber,Quantity,IsPOP,Location,strNPOP,chrSepar)
  297.         dim fso,objTextStream,arrLine,strLine,i,dictParts,strPrompt
  298.         set dictParts=CreateObject("scripting.Dictionary")
  299.         set fso=CreateObject("scripting.FileSystemObject")
  300.         set objTextStream=fso.OpenTextFile(strFile,ForReading,false,-2)
  301.         'check bom file format
  302.         'skip useless lines
  303.         for i=2 to HeaderLine
  304.                 objTextStream.SkipLine
  305.         next
  306.         strLine=objTextStream.ReadLine
  307.         for each item in Array(PartNumber,Quantity,IsPOP,Location)
  308.                 if not IncludesItemOf(strLine,item) then
  309.                         MsgBox "BOM file format check failed." & vbNewLine &_
  310.                                 "Expect """ & Join(Split(item,","),""" or """) & """ on line " & HeaderLine &_
  311.                                 " of " & strFile & "." & vbNewLine &vbNewLine &_
  312.                                 "Solutions:" & vbNewLine &_
  313.                                 "1.Check value of ""HeaderLine"" in setup.ini;" &_
  314.                                 vbNewLine & "2.Check your bom file " & strFile & ".", _
  315.                                 vbOkOnly+vbCritical,"Error"
  316.                         WScript.Quit
  317.                 end if
  318.         next
  319.        
  320.         'get column numbers to a dictionary
  321.         'dictColumn.Item("NPOP") coantains all NPOP column numbers, separated by comma
  322.         dim dictColumn                'dictionary to hold column numbers(0-based), keys are column name strings
  323.         set dictColumn=CreateObject("scripting.Dictionary")
  324.         arrLine=split(strLine,vbTab)
  325.         for i=0 to UBound(arrLine)
  326.                 select case arrLine(i)
  327.                         case PartNumber
  328.                                 dictColumn.Add PartNumber,i
  329.                         case Quantity
  330.                                 dictColumn.Add Quantity,i
  331.                         case Location
  332.                                 dictColumn.Add Location,i
  333.                         case else
  334.                                 if IncludesItemOf(arrLine(i),IsPOP) then
  335.                                         if not dictColumn.Exists("NPOP") then
  336.                                                 dictColumn.Add "NPOP",Cstr(i)
  337.                                         else
  338.                                                 dictColumn.Item("NPOP")=dictColumn.Item("NPOP") & "," & CStr(i)
  339.                                         end if
  340.                                 end if
  341.                 end select
  342.         next
  343.        
  344.         'skip useless lines       
  345.         for i=1 to StartLine-HeaderLine-1
  346.                 objTextStream.SkipLine
  347.         next
  348.        
  349.         'begin to read
  350.         do until objTextStream.AtEndOfStream
  351.                 strLine=objTextStream.ReadLine
  352.                 dim currentPN        'current part number
  353.                 dim objPart                'a 'part' object to hold each part's information
  354.                 arrLine=split(strLine,vbTab)
  355.                 if not PartIsNPOP(arrLine,dictColumn.Item("NPOP"),strNPOP) then
  356.                 'if this part is not NPOP
  357.                         if not arrLine(dictColumn.item(PartNumber))="" then
  358.                         'if part number column is not empty
  359.                                 currentPN=arrLine(dictColumn.item(PartNumber))
  360.                                 if not dictParts.Exists(currentPN) then
  361.                                 'if current part number is new
  362.                                         set objPart=new part
  363.                                         objPart.PartNumber=arrLine(dictColumn.item(PartNumber))
  364.                                         objPart.Quantity=arrLine(dictColumn.item(Quantity))
  365.                                         objPart.Location=arrLine(dictColumn.item(Location))
  366.                                         dictParts.Add currentPN,objPart
  367.                                 else
  368.                                 'if current part number is old
  369.                                         dictParts.item(currentPN).Quantity= _
  370.                                                 dictParts.item(currentPN).Quantity+ _
  371.                                                 arrLine(dictColumn.item(Quantity))
  372.                                         dictParts.item(currentPN).Location= _
  373.                                                 dictParts.item(currentPN).Location & "," & _
  374.                                                 arrLine(dictColumn.item(Location))
  375.                                 end if
  376.                         else
  377.                                 'if part number column is empty
  378.                                 'append location string
  379.                                 if not IsEmpty(currentPN) then
  380.                                         dictParts.item(currentPN).Location= _
  381.                                                 dictParts.item(currentPN).Location &_
  382.                                                 arrLine(dictColumn.item(Location))
  383.                                 end if
  384.                         end if
  385.                 else
  386.                 'if part is NPOP, clear currentPN
  387.                         currentPN=Empty
  388.                 end if
  389.         loop
  390.        
  391.         'delete ZZ and empty part numbers from the dictionary
  392.         'and check repeated locations
  393.         dim strAllLocations                 'string to hold all locations
  394.         for each item in dictParts.Items
  395.                 if item.IsBadPN() then
  396.                         dictParts.Remove(item.PartNumber)
  397.                 else
  398.                         strAllLocations=strAllLocations & "," & item.Location
  399.                 end if
  400.         next
  401.         dim dictRepeat                                                'dictionary to hold repeated items and times
  402.         set dictRepeat=CreateObject("scripting.Dictionary")
  403.         set dictRepeat=CheckRepeat(strAllLocations,",")
  404.         if dictRepeat.Count>0 then
  405.                 strPrompt=Empty
  406.                 strPrompt="BomKit detects repeated locations:" & vbNewLine &_
  407.                         vbNewLine & "Location" & vbTab & vbTab & "Repeat Times" & vbNewLine
  408.                 for each item in dictRepeat.Keys
  409.                         strPrompt=strPrompt &_
  410.                                 item & vbTab & vbTab & dictRepeat.Item(item) & vbNewLine
  411.                 next
  412.                 MsgBox strPrompt,vbOkOnly+vbCritical,"Error"
  413.                 WScript.Quit
  414.         end if
  415.        
  416.         'check partnumber quantities' correctness
  417.         strPrompt=Empty
  418.         for each item in dictParts.Items
  419.                 if not item.CheckQty then
  420.                         strPrompt=strPrompt & item.PartNumber & String(2,vbTab) &_
  421.                                 item.Quantity & vbTab & item.RealQty() & vbNewLine
  422.                         item.CorrectQty
  423.                 end if
  424.         next
  425.         if not IsEmpty(strPrompt) then
  426.                 strPrompt="BomKit detects wrong quantities, modified automatically:" & vbNewLine &_
  427.                         vbNewLine & "Part number" & String(2,vbTab) & "Read" & vbTab &_
  428.                         "Real" & vbNewLine & strPrompt
  429.                 MsgBox strPrompt,vbInformation,"Wrong Quantity"
  430.         end if
  431.        
  432.         objTextStream.Close
  433.         set ReadTextParts=dictParts
  434. end function

  435. 'function to check repeated items, separated by strSepar, in string specified by strTest
  436. 'return a dictionary to hold these items, keys are items, items are repeating times
  437. function CheckRepeat(strTest,strSepar)
  438.         dim strToCheck
  439.         strToCheck=strTest
  440.         if not Left(strToCheck,1)=strSepar then strToCheck=strSepar & strToCheck
  441.         if not Right(strToCheck,1)=strSepar then strToCheck=strToCheck & strSepar
  442.         dim dictRepeat
  443.         set dictRepeat=CreateObject("scripting.Dictionary")
  444.         for each item in split(strToCheck,strSepar)
  445.                 if InStr(strToCheck,strSepar & item & strSepar)<> _
  446.                    InStrRev(strToCheck,strSepar & item & strSepar) then
  447.                         if dictRepeat.Exists(item) then
  448.                                 dictRepeat.Item(item)=dictRepeat.Item(item)+1
  449.                         else
  450.                                 dictRepeat.Add item,1
  451.                         end if
  452.                 end if
  453.         next
  454.         set CheckRepeat=dictRepeat
  455. end function

  456. 'function to check if strA(Tab as delimiter) includes any items of strB, which are separated by comma
  457. function IncludesItemOf(strA,strB)
  458.         IncludesItemOf=false
  459.         dim item,strLine
  460.         strLine="," & Join(Split(strA,vbTab),",") & ","
  461.         for each item in Split(strB,",")
  462.                 if Instr(strLine,"," & item & ",") then
  463.                         IncludesItemOf=true
  464.                         exit for
  465.                 end if
  466.         next
  467. end function

  468. 'function to check if part is NPOP
  469. 'NPOPColumns contains related NPOP column numbers
  470. 'arrLine contains the split columns
  471. function PartIsNPOP(arrLine,NPOPColumns,strNPOP)
  472.         dim item
  473.         PartIsNPOP=false
  474.         for each item in Split(NPOPColumns,",")
  475.                 if IncludesItemOf(arrLine(CInt(item)),strNPOP) then
  476.                         PartIsNPOP=true
  477.                         exit for
  478.                 end if
  479.         next
  480. end function

  481. 'function to write part dictionary to Excel
  482. 'SmdPN,DipPN,PcbPN identify the part numbers read rom setup.ini
  483. sub WriteToExcel(dictParts,SmdPN,DipPN,PcbPN)
  484.         dim strInput                                                                'hold the string returned from InputBox
  485.         dim arrInput                                                                'array to hold split input string
  486.         dim arrLine
  487.         'get smd/dip/pcb part numbers from user
  488.         strInput=InputBox("Please enter SMD/DIP/PCB part numbers, separated by semicolons. Like:" &_
  489.                 vbNewLine & vbNewLine &_
  490.                 "55.5R101.S01G;55.5R101.D01G;48.5R101.0SA", _
  491.                 "Enter PNs",SmdPN & ";" & DipPN & ";" & PcbPN)
  492.         if strInput="" then WScript.Quit
  493.         arrInput=Split(strInput,";")
  494.         dim newSmdPN,newDipPN,newPcbPN
  495.         newSmdPN=UCase(Trim(arrInput(0)))
  496.         newDipPN=UCase(Trim(arrInput(1)))
  497.         newPcbPN=UCase(Trim(arrInput(2)))
  498.         if not UCase(SmdPN & DipPN & PcbPN)=(newSmdPN & newDipPN & newPcbPN) then
  499.         'if these part numbers are new, update and write them to setup.ini
  500.                 SmdPN=newSmdPN
  501.                 DipPN=newDipPN
  502.                 PcbPN=newPcbPN
  503.                 call WriteSetup(setupfile,strBegin,strEnd,"SmdPN",SmdPN)
  504.                 call WriteSetup(setupfile,strBegin,strEnd,"DipPN",DipPN)
  505.                 call WriteSetup(setupfile,strBegin,strEnd,"PcbPN",PcbPN)
  506.         end if
  507.        
  508.         'open excel to generate pre-BOM
  509.         dim objExcel,objWorkbook,objWorksheet
  510.         set objExcel=CreateObject("Excel.Application")
  511.         set objWorkbook=objExcel.Workbooks.Add
  512.         set objWorksheet=objWorkbook.Sheets(1)
  513.         objExcel.Visible=True
  514.         'Add header line
  515.         arrLine=Array("Assembly P/N","Assembly Class","Part Number", _
  516.                 "Priority","Mount Type","Quantity","Location")
  517.         for i=1 to UBound(arrLine)+1
  518.                 objWorksheet.Cells(1,i)=arrLine(i-1)
  519.         next
  520.         'add each part
  521.         dim row,IfExistsRed
  522.         row=2
  523.         IfExistsRed=false
  524.         for each item in dictParts.Items
  525.                 objWorksheet.Cells(row,1)=SmdPN
  526.                 objWorksheet.Cells(row,2)="EE"
  527.                 objWorksheet.Cells(row,3)=item.PartNumber
  528.                 objWorksheet.Cells(row,4)=1
  529.                 objWorksheet.Cells(row,5)="S"
  530.                 objWorksheet.Cells(row,6)=item.Quantity
  531.                 objWorksheet.Cells(row,7)=item.Location
  532.                 if item.PNmayDip then
  533.                 'if part may be Dip, mark with red
  534.                         IfExistsRed=true
  535.                         objWorksheet.Cells(row,1).Interior.ColorIndex=3
  536.                         objWorksheet.Cells(row,5).Interior.ColorIndex=3
  537.                 end if
  538.                 row=row+1
  539.         next
  540.         'sort by part numbers
  541.         dim objRange,objC1
  542.         const Ascending=1,Descending=2,HeaderLineYes=1
  543.         set objRange=objWorksheet.UsedRange
  544.         set objC1=objExcel.Range("C1")
  545.         objRange.Sort objC1,Ascending,,,,,,HeaderLineYes
  546.         'Insert two lines
  547.         objWorksheet.Rows(2).Insert
  548.         arrLine=Array(SmdPN,"EE",PcbPN, _
  549.                 1,"S","1")
  550.         for i=1 to UBound(arrLine)+1
  551.                 objWorksheet.Cells(2,i)=arrLine(i-1)
  552.                 objWorksheet.Cells(2,i).Font.ColorIndex=5
  553.         next
  554.         objWorksheet.Rows(2).Insert
  555.         arrLine=Array(DipPN,"EE",SmdPN, _
  556.                 1,"D","1")
  557.         for i=1 to UBound(arrLine)+1
  558.                 objWorksheet.Cells(2,i)=arrLine(i-1)
  559.                 objWorksheet.Cells(2,i).Font.ColorIndex=5
  560.         next
  561.         'auto filter
  562.         objRange.EntireColumn.AutoFilter
  563.         'Auto fit
  564.         objRange.EntireColumn.AutoFit()
  565.         if IfExistsRed then MsgBox "pre-BOM has been generated. Please check those values marked by red."
  566. end sub

  567. 'function to read parts from excel
  568. 'strFile points to the Excel file
  569. 'HeaderLine and StartLine identify the header line and first useful line
  570. 'PartNumber,ParentPN,Quantity,Location,Level are column names
  571. function ReadExcelParts(strFile,HeaderLine,StartLine,PartNumber,ParentPN,Quantity,Location,Level)
  572.         dim objExcel,objWorkbook,objWorksheet
  573.         set objExcel=CreateObject("Excel.Application")
  574.         set objWorkbook=objExcel.Workbooks.Open(strFile)
  575.         set objWorksheet=objWorkbook.Sheets(1)
  576.         dim dictParts
  577.         set dictParts=CreateObject("scripting.Dictionary")
  578.        
  579.         'Get column numbers to a dictionary
  580.         dim dictColumn,i,item,found
  581.         set dictColumn=CreateObject("scripting.Dictionary")
  582.         for each item in Array(PartNumber,ParentPN,Quantity,Location,Level)
  583.                 found=false
  584.                 for i=1 to objWorkSheet.UsedRange.Columns.Count
  585.                         if UCase(objWorksheet.Cells(HeaderLine,i))=UCase(item) then
  586.                                 found=true
  587.                                 dictColumn.Add item,i
  588.                                 exit for
  589.                         end if
  590.                 next
  591.                 if found=false then
  592.                         MsgBox "Excel BOM format check failed." & vbNewLine &_
  593.                                 "Expect """ & item & """ on line " & HeaderLine &_
  594.                                 " of " & strFile & "." & vbNewLine &vbNewLine &_
  595.                                 "Solutions:" & vbNewLine &_
  596.                                 "1.Check value of ""HeaderLine"" in setup.ini;" &_
  597.                                 vbNewLine & "2.Check your Excel file " & strFile & ".", _
  598.                                 vbOkOnly+vbCritical,"Error"
  599.                         WScript.Quit
  600.                 end if
  601.         next
  602.        
  603.         'begin to read parts
  604.         dim objPart,PreviousPN        'PreviousPN refers to the last main source part number
  605.         for i=StartLine to objWorkSheet.UsedRange.Rows.Count
  606.                 if Instr(UCase("12A"),UCase(objWorksheet.Cells(i,dictColumn.Item(Level)))) then
  607.                 'if the row is useful
  608.                         set objPart=new part
  609.                         objPart.PartNumber=objWorksheet.Cells(i,dictColumn.item(PartNumber))
  610.                         objPart.Quantity=objWorksheet.Cells(i,dictColumn.item(Quantity))
  611.                         objPart.Location=objWorksheet.Cells(i,dictColumn.item(Location))
  612.                         objPart.strSepar=" "
  613.                         objPart.ParentPN=objWorksheet.Cells(i,dictColumn.item(ParentPN))
  614.                         objPart.boolIsSecond=(UCase(objWorksheet.Cells(i,dictColumn.item(Level)))="A")
  615.                         if objPart.boolIsSecond then
  616.                         'if this part is a second source
  617.                                 objPart.MainSource=PreviousPN
  618.                                 dictParts.Add objPart.PartNumber & "-" & objPart.MainSource,objPart
  619.                         else
  620.                         'if this part is a main source
  621.                                 dictParts.Add objPart.PartNumber,objPart
  622.                                 PreviousPN=objPart.PartNumber
  623.                         end if
  624.                 end if
  625.         next
  626.         objExcel.Quit
  627.         Set ReadExcelParts=dictParts
  628. end function

  629. 'function to compare two part dictionary specified by dictFirstParts,dictSecondParts
  630. 'returns an array, which:
  631. 'array(0):a string including part numbers only in the first dictionary
  632. 'array(1):a string including part numbers only in the second dictionary
  633. 'array(2):a string including mismatched locations
  634. function CompareDicts(dictFirstParts,dictSecondParts)
  635.         dim arrCompare,dictCompared,item
  636.         arrCompare=Array("","","")
  637.         'based on dictFirstParts to compare dictSecondParts
  638.         dim arrLack
  639.         for each item in dictFirstParts.Keys
  640.                 if dictSecondParts.Exists(item) then
  641.                 'if dictSecondParts contains the part number with the same IsSecond property
  642.                         if not dictFirstParts.Item(item).boolIsSecond then
  643.                         'if this part is not second source, for there is no need to compare 2nd source
  644.                                 arrLack=CompareLocation( _
  645.                                         Split(dictFirstParts.Item(item).Location, _
  646.                                         dictFirstParts.Item(item).strSepar), _
  647.                                         Split(dictSecondParts.Item(item).Location, _
  648.                                         dictSecondParts.Item(item).strSepar))
  649.                                 if not Join(arrLack)=" " then
  650.                                 'if mismatch is found
  651.                                         arrCompare(2)=arrCompare(2) & "Part Number:" & dictFirstParts.Item(item).PartNumber & vbNewLine &_
  652.                                          "1st  Quantity:" & dictFirstParts.Item(item).Quantity & vbNewLine &_
  653.                                          "1st  Location:" & dictFirstParts.Item(item).Location & vbNewLine &_
  654.                                          "2nd  Quantity:" & dictSecondParts.Item(item).Quantity & vbNewLine &_
  655.                                          "2nd  Location:" & dictSecondParts.Item(item).Location & vbNewLine &_
  656.                                          "Is 2nd Source:" & dictFirstParts.Item(item).boolIsSecond & vbNewLine
  657.                                          if not dictFirstParts.Item(item).ParentPN="Unknown" then
  658.                                                  arrCompare(2)=arrCompare(2) & "Parent PN:" & dictFirstParts.Item(item).ParentPN & vbNewLine
  659.                                          elseif not dictSecondParts.Item(item).ParentPN="Unknown" then
  660.                                                  arrCompare(2)=arrCompare(2) & "Parent PN:" & dictSecondParts.Item(item).ParentPN & vbNewLine
  661.                                          else
  662.                                                  arrCompare(2)=arrCompare(2) & "Parent PN:" & dictFirstParts.Item(item).ParentPN & vbNewLine
  663.                                          end if
  664.                                                 
  665.                                          if not arrLack(0)="" then
  666.                                                  arrCompare(2)=arrCompare(2) & "Only in 1st:" & arrLack(0) & vbNewLine
  667.                                          end if
  668.                                          if not arrLack(1)="" then
  669.                                                  arrCompare(2)=arrCompare(2) & "Only in 2nd:" & arrLack(1) & vbNewLine
  670.                                          end if
  671.                                          arrCompare(2)=arrCompare(2) & vbNewLine
  672.                                 end if
  673.                         end if
  674.                 else
  675.                 'if dictSecondParts doesn't contain part number with the same IsSecond property
  676.                         arrCompare(0)=arrCompare(0) & "Part Number:" & dictFirstParts.Item(item).PartNumber & vbNewLine &_
  677.                                          "Quantity:" & dictFirstParts.Item(item).Quantity & vbNewLine &_
  678.                                          "Location:" & dictFirstParts.Item(item).Location & vbNewLine &_
  679.                                          "Parent PN:" & dictFirstParts.Item(item).ParentPN & vbNewLine &_
  680.                                          "Is 2nd Source:" & dictFirstParts.Item(item).boolIsSecond & vbNewLine
  681.                         if dictFirstParts.Item(item).boolIsSecond then
  682.                                 arrCompare(0)=arrCompare(0) & "Main Source:" &_
  683.                                  dictFirstParts.Item(item).MainSource & vbNewLine
  684.                         end if
  685.                         arrCompare(0)=arrCompare(0) & vbNewLine
  686.                 end if
  687.         next
  688.        
  689.         'based on dictFirstParts to compare dictSecondParts
  690.         for each item in dictSecondParts.Keys
  691.                 if not dictFirstParts.Exists(item) then
  692.                 'if dictFirstParts doesn't contain part number with the same IsSecond property
  693.                         arrCompare(1)=arrCompare(1) & "Part Number:" & dictSecondParts.Item(item).PartNumber & vbNewLine &_
  694.                                          "Quantity:" & dictSecondParts.Item(item).Quantity & vbNewLine &_
  695.                                          "Location:" & dictSecondParts.Item(item).Location & vbNewLine &_
  696.                                          "Parent PN:" & dictSecondParts.Item(item).ParentPN & vbNewLine &_
  697.                                          "Is 2nd Source:" & dictSecondParts.Item(item).boolIsSecond & vbNewLine
  698.                         if dictSecondParts.Item(item).boolIsSecond then
  699.                                 arrCompare(1)=arrCompare(1) & "Main Source:" &_
  700.                                  dictSecondParts.Item(item).MainSource & vbNewLine
  701.                         end if
  702.                         arrCompare(1)=arrCompare(1) & vbNewLine
  703.                 end if
  704.         next
  705.         CompareDicts=arrCompare
  706. end function

  707. 'function to check the difference between two arrays
  708. 'return an array to hold the results, which:
  709. 'array(0):only in the first array
  710. 'array(1):only in the second array
  711. function CompareLocation(arrayA,arrayB)
  712.         dim arrLack,strA,strB,item
  713.         arrLack=Array("","")
  714.         strA="," & Join(arrayA,",") & ","
  715.         strB="," & Join(arrayB,",") & ","
  716.         for each item in arrayA
  717.                 if Instr(strB,item)=0 then arrLack(0)=arrLack(0) & "," & item
  718.         next
  719.         for each item in arrayB
  720.                 if Instr(strA,item)=0 then arrLack(1)=arrLack(1) & "," & item
  721.         next
  722.         arrLack(0)=Mid(arrLack(0),2)
  723.         arrLack(1)=Mid(arrLack(1),2)
  724.         CompareLocation=arrLack
  725. end function

  726. '****************class area***************
  727. class part
  728.         private PN,Qty,Loc                    'PartNumber,Quantity,IsPOP,Location
  729.         private boolNormalPN                  'If Part Number is normal
  730.         public strSepar                                'separator to separate locations
  731.         public boolIsSecond                        'if this pard is 2nd source
  732.         public ParentPN                                'parent part number
  733.         public MainSource                        'Main source when it's 2nd source
  734.        
  735.         'Part Number property
  736.         property let PartNumber(strPartNumber)
  737.                 if strPartNumber="" then
  738.                         Err.Raise 101,"BomKit check error","Detected empty part number " & strPartNumber
  739.                 end if
  740.                 PN=strPartNumber
  741.                 call CheckPN()
  742.         end property
  743.         property get PartNumber()
  744.                 PartNumber=PN
  745.         end property
  746.        
  747.         'Quantity property
  748.         property let Quantity(intQuantity)
  749.                 Qty=CInt(intQuantity)
  750.                 if Qty<0 then
  751.                         Err.Raise 102,"BomKit check error","Negative Quantity " & Qty
  752.                 end if
  753.         end property
  754.         property get Quantity()
  755.                 Quantity=Qty
  756.         end property
  757.        
  758.         'Location property
  759.         property let Location(strLocation)
  760.                 Loc=strLocation
  761.         end property
  762.         property get Location()
  763.                 Location=Loc
  764.         end property
  765.        
  766.         'sub to check if part number is 253/354 type
  767.         private sub CheckPN()
  768.                 dim re
  769.                 set re=new RegExp
  770.                 re.Pattern="^(\w{2}\.\w{5}\.\w{3}|\w{3}\.\w{5}\.\w{4})$"
  771.                 if re.Test(PN) then
  772.                         boolNormalPN=true
  773.                 else
  774.                         boolNormalPN=false
  775.                 end if
  776.         end sub
  777.        
  778.         'class initialize event
  779.         private sub Class_Initialize
  780.                 boolNormalPN=false
  781.                 PN=""
  782.                 Qty=0
  783.                 Loc=""
  784.                 strSepar=","
  785.                 boolIsSecond=false
  786.                 ParentPN="Unknown"
  787.                 MainSource="N/A"
  788.         end sub
  789.        
  790.         'function to check if Quantity is equal to the real length
  791.         public function CheckQty()
  792.                 CheckQty=(Qty=UBound(Split(Loc,strSepar))+1)
  793.         end function
  794.        
  795.         'sub to correct wrong quantity
  796.         public sub CorrectQty()
  797.                 Qty=RealQty()
  798.         end sub
  799.        
  800.         'function to return real quantity
  801.         public function RealQty()
  802.                 RealQty=UBound(Split(Loc,strSepar))+1
  803.         end function
  804.        
  805.         'function to show whether pn is normal
  806.         public function IsNormalPN()
  807.                 IsNormalPN=boolNormalPN
  808.         end function
  809.        
  810.         'function to check if part number is ZZ
  811.         public function IsBadPN()
  812.                 IsBadPN=false
  813.                 if Left(PN,2)="ZZ" then IsBadPN=true
  814.                 dim re
  815.                 set re=new RegExp
  816.                 re.Pattern="^\s*$"
  817.                 if re.Test(PN) then
  818.                         IsBadPN=true
  819.                 end if
  820.         end function
  821.        
  822.         'function to check if part number may be dip
  823.         public function PNmayDip()
  824.                 dim arrPN
  825.                 if boolNormalPN then
  826.                         arrPN=Split(PN,".")
  827.                         PNmayDip=(20<=CInt(arrPN(0)) and CInt(arrPN(0))<=60)
  828.                 else
  829.                         PNmayDip=true
  830.                 end if
  831.         end function
  832. end class
复制代码
发表于 2013-8-4 09:51:38 | 显示全部楼层
自从转了linux之后,才觉得像是vbs和批处理的缺点是不能跨平台,就我个人而言,推荐python。
python太强大了..嘛..当然在windows下批处理和python各有各的好处。
发表于 2014-1-25 13:24:00 | 显示全部楼层
干嘛用的这个?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 01:12 , Processed in 0.024979 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表