Τετάρτη 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


Παρασκευή 23 Οκτωβρίου 2020

Αναθεώρηση 1, Έκδοση 10.

 Σε αυτήν την αναθεώρηση έγιναν μικρές προσθήκες και διορθώσεις. Επιπλέον ανέβηκε στο dropbox, γιατί η έκδοση 10 δεν είχε ανέβει (υπήρχε μόνο στο github),



Από το Readme.txt, επιγραμματικά στα ελληνικά. 

1. Διορθώθηκε η συνάρτηση Τραπ()  ή αλλιώς η στρογγύλευση του τραπεζίτη. Από λάθος έβγαινε πάντα θετική τιμή!

2. Μπήκε στα παράθυρα του χρήστη στο μενού ελέγχου η εντολή για αλλαγή μεγέθους από το πληκτρολόγιο (υπήρχε η αλλαγή θέσης). Οπότε ανοίξτε από το info το cs (διορθωτής c sharp) για να δείτε το μενού ελέγχου (πάνω αριστερά με τρεις οριζόντιες μικρές γραμμμές).

3. Η φόρμα της βοήθειας κάποιες φορές έβγαινε εκτός παραθύρου με συνέπεια να δουλεύει το alt+F4 για κλείσιμο (μετά άνοιγε κανονικά). Τώρα διορθώθηκε ώστε ποτέ να μην μεγαλώνει έξω από την οθόνη (από την πλέον αριστερή, από τις όποιες οθόνες)

4. Η Ένταση για τον ήχο τώρα λειτουργεί πολύ καλά για τα Windows 10. Επίσης ρυθμίζει και το αριστερό και δεξί κανάλι. Επίσης η μεταβλητή μόνο για ανάγνωση Ένταση δίνει την τιμή που ορίζουμε στον Πίνακα Ελέγχου των Windows, για την συγκεκριμένη εφαρμογή.

5. Στην εντολή Ήχος δίναμε όνομα αρχείου. Τώρα μπορούμε να δώσουμε και διάρθρωση μνήμης, φορτωμένη με αρχείο ήχου (wav) από το δίσκο (ή φτιάχνουμε δικό μας αν θέλουμε).

6, Η Ηχογράφηση υπήρχε στο κώδικα αλλά δεν ήταν γνωστή, ήθελε δουλειά και δεν την είχα τελειώσει. Δείτε την βοήθεια για αυτή την εντολή.

7. Μπήκε και μια μεταβλητή μόνο για ανάγνωση, η Ηχογράφησης.Επίπεδο που γυρίζει την στιγμιαία τιμή του ήχου όπως έρχεται στην εφαρμογή.

8. Έγιναν επεμβάσεις και στην εντολή Ταινία (και στο σύστημα γενικότερα του video).

9. Μπήκαν νέα προγράμματα στο Info. Από αυτά περισσότερο θα αναφέρω το console και το sprites. Το δεύτερο το έδειξα και στην παρουσίαση στο συνέδριο Η Πληροφορική στην Εκπαίδευση (12th CIE2020). Το cosnole είναι μια πρόταση για χρήση της κονσόλας των windows μέσα από την Μ2000, 

Στη φωτογραφία φαίνεται η κονσόλα που έχει ανοίξει μπροστά από την κονσόλα της Μ2000 σε καθορισμένη θέση (με εντολή μέσα από την Μ2000). Επίσης  βλέπουμε δυο ειδών prompt (εισαγωγικού μάρκου), το M2000> που δέχεται εντολές για τη Μ2000, στην ουσία τμήματα της Μ2000, και σε αυτή την φάση έχουμε μπλοκάρισμα ενός νήματος που παίζει στο περιθώριο (μπλοκάρισμα όταν διαβάζει η Μ2000 μέσω κονσόλας, επειδή διαβάζει γραμμές). Το δεύτερο μάρκο βγαίνει όταν ανοίξουμε μέσα στην ίδια κονσόλα το cmd.exe ή άλλη εφαρμογή, επειδή η άλλη εφαρμογή τρέχει σε δικό της χώρο! Τότε βλέπουμε το νήμα να εκτελείται κανονικά από πίσω! Και στη πρώτη περίπτωση αν τυπώνουμε μόνο στη κονσόλα δεν έχουμε μπλοκάρισμα. Έχει αφαιρεθεί το Χ από την πάνω αριστερή γωνία. Όμως αν κάποιος πατήσει το ctrl+c θα "ρίξει" και τη κονσόλα και τη Μ2000  από πίσω. Δίνοντας exit, γυρνάμε από το cmd στο αρχικό prompt και μετά πάλι με exit, ή με κενή γραμμή γυρνάμε στη κονσόλα της Μ2000. Από την κονσόλα των Windows η Print τυπώνει στην κονσόλα της Μ2000! για το λόγο αυτό φτιάχτηκε ένα τμήμα με όνομα Echo  για να εμφανίζει διάφορα νούμερα από τη Μ2000, στη κονσόλα.

Με κατάλληλο χειρισμό των αρχείων εισόδου και εξόδου μπορούμε να κάνουμε την Μ2000 να δουλεύει για redirection...ανακατεύθυνση εξόδου!





Τα RTL γράμματα δεν φαίνονται στη σωστή σειρά, αλλά μπήκαν εδώ για να φανεί ότι η κονσόλα των Windows παίρνει Unicode (πολύ περισσότερους από 256 διαφορετικούς χαρακτήρες).


10. Sprites demo:

Τα μεγαλώνουμε, τα γυρίζουμε (περιστρέφουμε ή κάνουμε οριζόντια αλλαγή - flip), τα μετακινούμε. Υπάρχει ένα σχέδιο και σε κάθε ένα ρίχνουμε ένα μερικώς διάφανο χρώμα και το χρωματίζουμε! Επίσης μπορούμε να γράψουμε πάνω στην εικόνα του sprite. Το χεράκι είναι και αυτό ένα sprite, και παίζει στη θέση του δείκτη του ποντικιού τον οποίο έχουμε αφαιρέσει!




Το αυθεντικό από το Readme.txt

1. Remove a bug from Bank() function (banker rounding) which casue a removing the minus sign

2. Added size command for controlbox for user forms (so now we can resize a form by using keyboard)

3. Prevent help form to get resize outside the screen

4. Volume statement works in Window 10, and now has a second parameter to reduce volumen from left or right channel

   Also Volume read only variable now reflect the original volume for the specific run, which show the windows control panel.

5. Sound statement now can use buffer from memory to play sounds.

6. SoundRec statement for recording (program in help file)

7. SoundRec.level  as a read only variable

8. Movie statement fix for Windows 10

9. A new example in Info file, console, or how we can use console (same as cmd.exe console) from M2000, using Win 32 api from M2000 code.

10. Sprites a demo as used for my contribution to a CIE 2020 12th Conference on Informatics in Education