Τετάρτη 28 Οκτωβρίου 2020

Αναθεώρηση 3 και 4, Έκδοση 10 και παράδειγμα με αρχείο xlsx

Σε αυτές τις αναθεωρήσεις έφτιαξα δυο προβληματάκια. Ένα είχε να κάνει με handlers του συστήματος γραφικών. Σε μια λειτουργία είχα ξεχάσει μια γραμμή να τη σβήσω, με συνέπεια να βγάζει έναν νέο handler χωρίς να υπάρχει αντίστοιχη εντολή για διαγραφή. Κάθε εφαρμογή των Win32, έχει όριο τους 10000 handlers. Μόλις τους φτάσει "καθάρισε". Μπορεί κανείς να εποπτεύει τη χρήση τους από τη διαχείριση διεργασιών.

Παράδειγμα με αρχείο xlsx

Επειδή δεν έχω excel στον υπολογιστή, για να το ανοίξω ως COM αντικείμενο και να πάρω τις τιμές από το πρόγραμμα, θα το ανοίξω με χρήση ODBC, όπου δηλώνω το τρόπο πρόσβασης στο λεγόμενο αλφαριθμητικό σύνδεσης (connection string). Οι εντολές για βάσεις δεδομένων παίρνουν πρώτο όρισμα ή το όνομα της βάσης ως αρχείο mdb, ή σε παρένθεση ένα όνομα που θέλουμε και για τον διερμηνευτή σημαίνει ότι έχουμε δώσει τη σύνδεση στο αλφαριθμητικό σύνδεσης.

Επειδή οι στήλες Unit QTY και QTY έχουν και αριθμούς και αλφαριθμητικά δίνουμε στο σύνδεση το χαρακτηριστικό IMEX=1 με το οποίο όπου βρίσκει αλφαριθμητικά και αριθμούς σε στήλες τα κάνει αλφαριθμητικά. Εδώ μόνο η Item QTY είναι καθαρή, δηλαδή αριθμός. 

Υπάρχουν δυο προγράμματα, το ένα δίνει την εικόνα παρακάτω και το άλλο κάνει εκτύπωση (επιλογή σε pdf). Υπάρχει το αρχείο parts.xlsx καθώς και ένα zip αρχείο με την εξαγωγή (φαίνεται στη δεύτερη εικόνα).


Αρχείο parts.xlsx



// set the output console to 60X48
Form 60, 48
Cls 15, 0 ' White
Back {Cls 15,0}
Pen 0 ' Black
Double
Report 2, {Exporting Data from an xlsx file}
Normal
Italic 1
Report 2, {from Autodesk Inventor application}
Italic 0
// This is the original file that we open through ODBC driver
f$=dir$+"parts.xlsx"
Print Part $(9),"File: ",@(tab); f$
Print
// We have a excel file created from Inventor for parts of an assembly
// set the output to left justification, and adjust all letters/numbers to left border, also cut excluding letters from column width
// code 9 not use word cut but cut in letters
// see bellow where we place 60 for a temporary column definition in a $(9,60) in a Print Part
Print $(9)


file$=quote$(f$)
A$={Provider=Microsoft.ACE.OLEDB.12.0;Data Source=}+file$+{;Extended Properties="Excel 12.0 Xml;ReadOnly=0;HDR=YES; IMEX=1";}  ' all as text
Print "Connection string:",
Pen 5 {Report 3,A$, width-pos-4}
Cursor 0
Report 2, "File Structure Analysis"
db.provider a$,"ODBC",""
flush
Structure "(anyname)"
// We use Stack with no parameters to view the items of stack
// here the items are 1 "BOM$" 0
Print "Values in Stack:", : Stack
// so first item is number of tables, and the Next items are table name and number of indexes
// for each table, but here we get the first one
Read TablesNum
// If TablesNum=0 Then we get error
//Print TablesNum
Read Tablename$, TableIndexes
//Print Tablename$, TableIndexes
// So we flush all other values for other tables
Flush
// So now we get the structure of table Tablename$
// we have place IPEX=1 so we get TEXT where the column has mix types (strings and arithmetic)
Report 2, "Table Structure Analysis"
Structure "(anyname)", Tablename$
Read Many, drop1
Print $(4),
For i=1 to Many
      Read FieldName$, Type$, Bytes
      Print i, "["+FieldName$+"]", @(tab(3)), Type$, Bytes
Next i
Print $(9),
Retrieve "(anyname)", "Select * from ["+Tablename$+"]", 1,"",""
// Stack
Read Many
Print "Records:";Many
// remove all data from stack
flush
// because we use
Report 2, "Search for Part Number 0897-PA-0114-003"
Check("0897-PA-0114-003")
Report 2, "Search for items with Material from Steel, no assemblies, only parts, and display part numbers"
Search "(anyname)", Tablename$, 1,"Material", "Like", "%Steel%"
Read Many
i=1
// Using code 4 we place strings left justification but maybe using more than one columns
Print $(4),
Counter=0
Inventory AllItems
While Many>0
      Drop 2
      Read Ret$
      If Val(left$(Ret$, 3)) Else
            Counter++
            If Exist(AllItems, Ret$) Then
                  Return AllItems, Ret$:=AllItems(Ret$)+1
            Else
                  Append AllItems, Ret$:=1
            End If
      End If
      Flush
      many--
      i++
      If many Then
            Search "(anyname)", Tablename$, i,"Material", "Like", "%Steel%"
            Drop       
      End If
End While
Print
Print "Total:"; Counter
Report 2,"Group, Sort and Display"
Sort AllItems
Items=Each(AllItems)
i=1
While Items
      Print Part $(7, 4),~(7), Str$(i, "000"), $(4), ~(6), Eval$(Items!);~(3);" x ";Eval(Items)
      Print
      i++
End While
WaitKey$=Key$
Close base "(anyname)"
Sub Check(a$)
      SearchPart(a$, 1)
      Read Many
      If Many>0 Then
            local m$=""
            Read local codelist$
            Flush
            if many>1 then
                  local i
                  for i=2 to many
                        SearchPart(a$, i)
                        Drop
                        codelist$+=", "+Letter$
                  next i
                      m$="s x"+Str$(Many)
            end if
            
            ViewOne(codelist$, m$) ' all the values are in stack
      Else
            flush
      End If
End Sub
Sub SearchPart(a$, i)
Retrieve "(anyname)", Tablename$, i,"Part Number", a$
End Sub
Sub CheckMany()
      //stack
      Read Many
      If Many>0 Then
            Print "Found :";Many
            flush
      End If
End Sub
Sub ViewOne(AllItems$, m$)
      Pen 4 {
            Read Local Filename$, Part$, BOM$, Item
            Read Local Unit$,Qty$,StockNum$, Desc$, Mass$, Material$, Project$, Rev$
            PrintValue("Item"+m$, AllItems$)
            PrintValue("File", Filename$)
            PrintValue("Part", Part$)
            PrintValue("BOM", BOM$)
            PrintNumValue("Item Qty", Item)
            PrintValue("Unit Qty", Unit$)
            PrintValue("Qty",Unit$)
            PrintValue("StockNum", StockNum$)
            PrintValue("Desc", Desc$)
            PrintValue("Mass", Mass$)
            PrintValue("Material", Material$)
            PrintValue("Project", Project$)
            PrintValue("Rev", Rev$)
      }
End Sub


Sub PrintNumValue(A$, B)
      Pen 1 {
            Print A$,
      }
      Print Part @(tab),$(4); B
      Print
End Sub
Sub PrintValue(A$, B$)
      Pen 1 {
            Print A$,
      }
      Print Part @(tab), $(9, 60), B$
      Print
End Sub


Και εδώ είναι η εκτύπωση σε Pdf:




Zip αρχείο με το pdf.

flush
f$=dir$+"parts.xlsx"
file$=quote$(f$)
A$={Provider=Microsoft.ACE.OLEDB.12.0;Data Source=}+file$+{;Extended Properties="Excel 12.0 Xml;ReadOnly=0;HDR=YES; IMEX=1";}


db.provider a$,"ODBC",""


structure "(anyname)"
Read TablesNum, Tablename$, TableIndexes
Flush
structure "(anyname)", Tablename$
read Many, drop1
Retrieve "(anyname)", "Select * from ["+Tablename$+"]", 1,"",""
Read Many
flush
Printer {
      Linespace 0
      Form 80,66
      Pen 0
      Double
      Report f$
      Normal
      Cursor 0,3
      PageNo=1
      for i=1 to Many
      Layer {Print i: refresh}
      st$="Select * from ["+Tablename$+"]"
      Retrieve "(anyname)", st$, i,"",""
      Drop ' drop an item from stack (the count number of records, same as Many variable)
      Read Item$, Filename$, Part$, BOM$, Item
      Read Unit$,Qty$,StockNum$, Desc$, Mass$, Material$, Project$, Rev$
      Print Over ~(15,7,7), "A/A ["; I;"]"
      Print Under
      ViewOne()
      if i mod 4=0 and i<many then
            Cursor 0, height-1
            Print Part $(6, width), "- "+Str$(PageNo,"")+" -"
            PageNo++
            Page
            cursor 0,0
            Double
                  report f$
            Normal
            Cursor 0,3
      end if
      wait 10
      Next
      i--
      if i mod 4<>0 then
            Cursor 0, height-1
            Print Part $(6, width), "- "+Str$(PageNo,"")+" -"
      end if
}


wait 2000
CLOSE BASE "(anyname)"


Sub ViewOne()
            Print $(9),
            PrintValue("Item", Item$)
            PrintValue("File", Filename$)
            PrintValue("Part", Part$)
            PrintValue("BOM", BOM$)
            PrintNumValue("Item Qty", Item)
            PrintValue("Unit Qty", Unit$)
            PrintValue("Qty",Unit$)
            PrintValue("StockNum", StockNum$)
            PrintValue("Desc", Desc$)
            PrintValue("Mass", Mass$)
            PrintValue("Material", Material$)
            PrintValue("Project", Project$)
            PrintValue("Rev", Rev$)
            Print $(4),
End Sub
Sub PrintNumValue(A$, B)
      Pen 1 {
            Print A$,
      }
      Print Part @(tab),$(4); B
      Print
End Sub
Sub PrintValue(A$, B$)
      Pen 1 {
            Print A$,
      }
      Print Part @(tab), $(9, 60), B$
      Print
End Sub


Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.