Μετονομάστε ένα φύλλο από «Summary» σε «Overview» σε ένα βιβλίο εργασίας που δημιουργήθηκε προγραμματιστικά, και κάθε εσωτερικός υπερσύνδεσμος που έδειχνε στο Summary!A1 παύει να οδηγεί πουθενά. Καμία εξαίρεση κατά την αποθήκευση, καμία κατά το άνοιγμα. Ο σύνδεσμος εξακολουθεί να αποδίδεται, εξακολουθεί να φαίνεται πατήσιμος, και σιωπηλά καταλήγει στο πουθενά. Το ίδιο είδος βλάβης εμφανίζεται και μετά από μια μετατροπή save-as ή μια μετάβαση .xls/.xlsx και επιστροφή, όταν ένα σχόλιο προσγειώνεται μια στήλη παραδίπλα ή ένας σχετικός σύνδεσμος χάνει τον στόχο του. Και τα δύο χαρακτηριστικά κουβαλούν κατάσταση αναθεώρησης πάνω στην οποία ενεργούν πραγματικοί άνθρωποι, οπότε όταν χαλάνε η αστοχία είναι αόρατη μέχρι να κάνει κλικ ένας αναθεωρητής και να μη συμβεί τίποτα
Αυτός είναι ο πρακτικός λόγος για τον οποίο τα σχόλια και οι υπερσύνδεσμοι χρειάζονται περισσότερη προσοχή απ' όσο υποδηλώνει η κοσμητική τους εμφάνιση. Το HotXLS δίνει σε κώδικα Delphi και C++Builder απευθείας πρόσβαση εγγραφής και στα δύο, σε XLS και XLSX, χωρίς Excel automation στη μέση. Η άλλη όψη αυτού του ελέγχου είναι η ευθύνη: η βιβλιοθήκη γράφει ακριβώς τους στόχους που της δίνετε και δεν επικυρώνει κανέναν από αυτούς, οπότε η διατήρηση ακέραιης της ροής αναθεώρησης είναι δουλειά του δικού σας κώδικα, όχι του Excel
Σχόλια κελιών ως εγγραφές αναθεώρησης γραμμένες από μηχανή
Στο μοντέλο κλάσεων XLSX, ένα σχόλιο είναι αντικείμενο σε επίπεδο φύλλου εργασίας: γνωρίζει τη γραμμή του, τη στήλη του, έναν συγγραφέα και ένα σώμα κειμένου. Το πεδίο συγγραφέα δικαιολογεί τη θέση του. Όταν ένα βιβλίο εργασίας που δημιούργησε ο κώδικάς σας διασχίζει μια αλυσίδα αναθεώρησης, η πρώτη ερώτηση που θέτει ένας ελεγκτής είναι ποιος έγραψε μια συγκεκριμένη σημείωση, και μια σημείωση που μένει χωρίς συγγραφέα απαντά σε αυτή την ερώτηση με ένα κενό. Σφραγίστε τα σχόλια που δημιουργείτε με μια ταυτότητα υπηρεσίας ώστε η προέλευση να μην είναι ποτέ αμφίβολη
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Note: TXLSXComment;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('reconciliation.xlsx');
Sheet := Book.Sheets[0];
// Σημείωση με συγγραφέα για το προσαρμοσμένο νούμερο
Sheet.AddComment(14, 4, 'Manual adjustment: late FX rate, see ticket FIN-2214',
'recon-service');
// Ενημέρωση υπάρχουσας σημείωσης αντί για προσθήκη δεύτερης από πάνω
Note := Sheet.Comments.FindAt(14, 4);
if Note <> nil then
Note.Text := Note.Text + ' [verified 2026-06-11]';
Book.SaveAs('reconciliation-reviewed.xlsx');
finally
Book.Free;
end;
end;
Η δοκιμή FindAt έχει μεγαλύτερη σημασία απ' όσο φαίνεται. Μια παρτίδα εργασιών που επαναλαμβάνεται μετά από μια παροδική αποτυχία θα καλέσει πρόθυμα την AddComment για δεύτερη φορά σε ένα κελί που έχει ήδη σχολιάσει, και το κελί καταλήγει με δύο σωρευμένες σημειώσεις που κανείς δεν ζήτησε. Δοκιμάστε πρώτα με την FindAt και ενημερώστε το αντικείμενο που επιστρέφει. Η συλλογή Comments εκθέτει επίσης τις DeleteAt και DeleteInRange. Αυτή η παραλλαγή εύρους είναι αυτή που πρέπει να χρησιμοποιήσετε όταν καθαρίζετε ένα βιβλίο εργασίας πριν φύγει από τον οργανισμό: η εκκαθάριση εσωτερικών σημειώσεων QA από μια ολόκληρη περιοχή είναι μία και μόνο κλήση αντί για έναν χειρόγραφο βρόχο πάνω από τα κελιά
Τα εξωτερικά URL και τα άλματα εντός βιβλίου εργασίας είναι διαφορετικά API
Το OOXML διατηρεί τα δύο είδη συνδέσμων σε διαφορετικές θέσεις. Ένα εξωτερικό URL γίνεται καταχώριση σχέσης (relationship) στο τμήμα .rels του φύλλου, με το κελί να δείχνει στη σχέση μέσω id. Ένα εσωτερικό άλμα δεν αγγίζει καθόλου το επίπεδο σχέσεων· είναι ένα απλό αλφαριθμητικό θέσης, όπως το Summary!A1, αποθηκευμένο απευθείας πάνω στον σύνδεσμο. Το HotXLS διατηρεί αυτή τη διάκριση ορατή στο API αντί να υπερφορτώνει μία μέθοδο, πράγμα που σημαίνει ότι επιλέγετε τη σωστή κλήση γνωρίζοντας πού βρίσκεται ο στόχος:
Sheet.Cells[2, 1].Value := 'Source record';
Sheet.AddHyperlink(2, 1, 'https://intranet.example.com/records/2214',
'Open record 2214', 'ERP source entry');
Sheet.Cells[3, 1].Value := 'Totals';
Sheet.AddHyperlinkToCell(3, 1, 'Overview!B12', 'Jump to totals');
Στο αντικείμενο TXLSXHyperlink που προκύπτει, οι ιδιότητες Url και Location είναι αμοιβαία αποκλειόμενες, και η IsInternal σας λέει ποια από τις δύο έχει τιμή. Αυτή τη σημαία ελέγχετε όταν απογράφετε τους συνδέσμους σε ένα ανοιγμένο βιβλίο εργασίας και χρειάζεται να μεταχειριστείτε το «φεύγει από το αρχείο» και το «μένει μέσα στο αρχείο» με διαφορετικούς κανόνες: ένας εξωτερικός κεντρικός υπολογιστής μπορεί να αντιμετωπίζει μια λίστα επιτρεπόμενων, ενώ ένας εσωτερικός στόχος χρειάζεται μόνο να ονομάζει ένα φύλλο που υπάρχει. Οι εσωτερικοί σύνδεσμοι δεν φέρουν κανένα τμήμα σχέσης από πίσω τους, κάτι που τους κάνει επίσης φθηνότερους στην αναγραφή τους μαζικά
Η βλάβη από την εισαγωγή βρίσκεται εξ ολοκλήρου στην εσωτερική πλευρά, και προκύπτει από ένα γεγονός: ένα αλφαριθμητικό θέσης δεν είναι μια αναλυμένη αναφορά. Το HotXLS γράφει ακριβώς το κείμενο που του δίνετε, και τίποτα δεν ξαναδείχνει αυτό το κείμενο όταν ένα φύλλο μετονομάζεται αργότερα. Δύο άμυνες αντέχουν στην πράξη. Η πρώτη είναι πειθαρχία στη σειρά: μετονομάστε κάθε φύλλο πριν δημιουργήσετε έστω και έναν σύνδεσμο, και κατόπιν αντιμετωπίστε τα ονόματα φύλλων ως παγωμένα αναγνωριστικά. Η δεύτερη είναι πιο ανθεκτική και επιβιώνει σε μετονομασίες που γίνονται εκ των υστέρων. Στοχεύστε τον σύνδεσμο σε ένα defined name σε επίπεδο βιβλίου εργασίας αντί σε μια ακατέργαστη διεύθυνση Sheet!Cell, επειδή το Excel ξαναγράφει τον ορισμό ενός ονόματος όταν αλλάζει το υποκείμενο φύλλο, οπότε ο σύνδεσμος ακολουθεί αυτόματα. Αυτή η δεύτερη προσέγγιση ταιριάζει φυσικά με τις τεχνικές στο defined names και cross-sheet formulas στο HotXLS
Η πλευρά XLS: ίδιες έννοιες, παλαιότερη υδραυλική
Η πρόσοψη BIFF8 κρεμά τα σχόλια από εύρη αντί από μια συλλογή σε επίπεδο φύλλου εργασίας. Καλείτε την AddComment πάνω σε ένα IXLSRange και παίρνετε πίσω ένα TXLSComment· η ιδιότητα Comment του εύρους διαβάζει μια υπάρχουσα σημείωση, και η ClearComments τις σβήνει όλες. Το λεπτό σημείο εδώ έχει να κάνει με τη θέση. Ένα TXLSComment δεν εκθέτει δημόσια τη δική του γραμμή και στήλη, οπότε ο φυσικός βρόχος, «διάτρεξε κάθε σχόλιο και ανάφερε πού βρίσκεται», λειτουργεί ανάποδα σε σχέση με το API. Πρέπει να ξεκινήσετε από τα κελιά. Είτε οδηγήστε τον έλεγχο από τη λίστα διευθύνσεων που σχολιάσατε, είτε κρατήστε το δικό σας αρχείο καταγραφής θέσεων καθώς γράφετε, γιατί το αντικείμενο σχολίου δεν θα σας πει αργότερα πού βρίσκεται
var
Book: IXLSWorkbook;
Sheet: IXLSWorksheet;
Remark: TXLSComment;
begin
Book := TXLSWorkbook.Create;
Sheet := Book.Sheets.Add;
Sheet.Name := 'Review';
Sheet.Cells.Item[5, 2].Value := 4821.50;
Remark := Sheet.Cells.Item[5, 2].AddComment('Awaiting sign-off from controller');
Remark.Visible := True; // άνοιξε τη σημείωση αμέσως, από την πρώτη προβολή
Sheet.AddHyperlink(7, 2, 'https://intranet.example.com/signoff/4821',
'Sign-off form', 'Opens the controller queue');
Book.SaveAs('review.xls');
end;
Ο ορισμός της Visible σε True είναι ο παλαιός τρόπος να γίνεται μια σημείωση αδύνατο να προσπεραστεί απαρατήρητη: το κίτρινο πλαίσιο μένει ανοιχτό πάνω στο φύλλο αντί να περιμένει ένα πέρασμα του δείκτη από πάνω. Η TXLSComment πηγαίνει ένα βήμα παραπέρα από το αντίστοιχό της στο XLSX εκθέτοντας την TextRuns, οπότε μία και μόνη σημείωση μπορεί να κουβαλήσει μια έντονη προειδοποίηση δίπλα σε μια απλή εξήγηση, μορφοποίηση που το API σχολίων του XLSX δεν εκθέτει με τον ίδιο τρόπο. Οι υπερσύνδεσμοι σε αυτή την πλευρά έρχονται μέσα από τρεις προοδευτικές υπερφορτώσεις (μόνο διεύθυνση, έπειτα με κείμενο εμφάνισης, έπειτα με screen tip) και διαβάζονται πίσω μέσα από τη συλλογή HyperLinks του φύλλου εργασίας, όπου κάθε σύνδεσμος εκθέτει τα Address, SubAddress, DisplayText, και ScreenTip
Ένα φύλλο ευρετηρίου αναθεώρησης νικά τις διάσπαρτες σημειώσεις
Μετά από περίπου μία δωδεκάδα σχολίων, το διάβασμα-με-πέρασμα-δείκτη σταματά σιωπηλά να κλιμακώνεται. Οι σημειώσεις συσσωρεύονται σε φύλλα που ένας αναθεωρητής δεν ανοίγει ποτέ, και αυτές που έχουν τη μεγαλύτερη σημασία είναι ακριβώς αυτές που είναι πιο εύκολο να χαθούν. Η δομή που έχει αποδειχθεί πιο ανθεκτική είναι ένα δημιουργημένο φύλλο ευρετηρίου: μία γραμμή ανά σχολιασμένη θέση, που καταγράφει το όνομα φύλλου της, τη διεύθυνση κελιού, τον συγγραφέα, και ένα σύντομο απόσπασμα της σημείωσης. Η τελευταία στήλη κουβαλά έναν εσωτερικό υπερσύνδεσμο χτισμένο με την AddHyperlinkToCell που πηδά κατευθείαν στο σχολιασμένο κελί. Τώρα ο αναθεωρητής διαβάζει μια λίστα προς τα κάτω αντί να ψάχνει σε ένα πλέγμα, και ο αριθμός γραμμών αυτού του ευρετηρίου λειτουργεί ταυτόχρονα και ως απογραφή σχολίων για το πέρασμα ελέγχου παρακάτω
Το ευρετήριο είναι φθηνό στην κατασκευή επειδή η γεννήτριά σας ήδη γνωρίζει κάθε θέση που άγγιξε. Προσθέστε μια πλειάδα (φύλλο, γραμμή, στήλη, συγγραφέας, περίληψη) σε μια λίστα καθώς γράφετε κάθε σχόλιο, και έπειτα εκδώστε το φύλλο ευρετηρίου τελευταίο ώστε ο αριθμός γραμμών του να είναι τελικός πριν την αποθήκευση. Δύο βελτιώσεις αποδίδουν: ταξινομήστε το ευρετήριο κατά σοβαρότητα ή κατά φύλλο αντί κατά σειρά εισαγωγής, και βάλτε έναν σύνδεσμο επιστροφής στην κεφαλίδα του ευρετηρίου ώστε ένας αναθεωρητής να μπορεί να επιστρέφει στην κορυφή μετά από κάθε στοιχείο. Επειδή οι εσωτερικοί σύνδεσμοι είναι απλά αλφαριθμητικά θέσης χωρίς τίποτα στο επίπεδο σχέσεων από πίσω τους, ακόμη και ένα ευρετήριο χιλίων γραμμών δεν προσθέτει σχεδόν τίποτα στο μέγεθος αρχείου ή στον χρόνο αποθήκευσης
Το ίδιο φύλλο αποδίδει ξανά στο ταξίδι επιστροφής. Όταν επιστρέφει το αναθεωρημένο βιβλίο εργασίας, ο κώδικάς σας διαβάζει τιμές κατάστασης πληκτρολογημένες σε κελιά δίπλα στις γραμμές του ευρετηρίου αντί να σαρώνει ξανά κάθε φύλλο για σχόλια που μπορεί να έχουν αλλάξει. Μια στήλη με δομημένα κελιά κατάστασης αναλύεται καθαρά· ένα σκόρπισμα σημειώσεων ελεύθερου κειμένου όχι
Ένα πέρασμα ελέγχου πριν την παράδοση που πράγματι εντοπίζει τη βλάβη
Κανένα από αυτά τα API δεν επικυρώνει έναν στόχο. Ένας σύνδεσμος προς ένα φύλλο που διαγράψατε, ένας κακογραμμένος κεντρικός υπολογιστής intranet, ένας κοινόχρηστος φάκελος αρχείων που καταργήθηκε το προηγούμενο τρίμηνο: όλα αποθηκεύονται χωρίς κανέναν ψίθυρο. Το ECMA-376 καθορίζει πώς αποθηκεύεται ένας σύνδεσμος, όχι ότι αυτός οδηγεί κάπου. Ένα βιβλίο εργασίας που κουβαλά μεταδεδομένα αναθεώρησης αξίζει επομένως ένα δικό του σύντομο στάδιο ελέγχου, που τρέχει ακριβώς πριν την SaveAs:
- Συγκεντρώστε κάθε εσωτερική θέση που γράφτηκε κατά τη δημιουργία και επιβεβαιώστε ότι το όνομα φύλλου πριν το θαυμαστικό εξακολουθεί να υπάρχει στη συλλογή φύλλων του βιβλίου εργασίας
- Ελέγξτε τα εξωτερικά URL έναντι μιας λίστας επιτρεπόμενων σχημάτων και κεντρικών υπολογιστών. Γυμνές διαδρομές
file://και UNC διαρρέουν λεπτομέρειες περιβάλλοντος και χαλάνε τη στιγμή που το αρχείο φεύγει από το δίκτυό σας - Μετρήστε τα σχόλια ανά φύλλο και συγκρίνετέ τα με αυτό που σκόπευε να γράψει η γεννήτριά σας. Μια επανάληψη που διπλασίασε τις σημειώσεις αναδεικνύεται εδώ αντί στα εισερχόμενα του αναθεωρητή
- Αφαιρέστε τις μόνο-εσωτερικές σημειώσεις με την
DeleteInRangeόποτε ο παραλήπτης βρίσκεται εκτός του οργανισμού
Ομάδες που χτίζουν τα βιβλία εργασίας τους από ένα επίπεδο δεδομένων μπορούν να ενσωματώσουν αυτό το στάδιο στο ίδιο βήμα διοχέτευσης που ήδη επικυρώνει τα δεδομένα, οπότε ο έλεγχος μεταδεδομένων ταξιδεύει δωρεάν μαζί του. Οι μηχανισμοί είναι αυτοί που περιγράφονται στο εξαγωγή αποτελεσμάτων ερωτημάτων βάσης δεδομένων σε αναφορές Excel, στραμμένοι προς συνδέσμους και σχόλια αντί για γραμμές
Μια λεπτομέρεια εισαγωγικών μπερδεύει τον κόσμο όταν χτίζουν αλφαριθμητικά θέσης με το χέρι. Ένα φύλλο του οποίου το όνομα περιέχει κενό πρέπει να μπαίνει σε εισαγωγικά μέσα στη θέση, ακριβώς όπως το βάζει σε εισαγωγικά η γραμμή τύπων: 'Quarterly Totals'!A1, όχι Quarterly Totals!A1. Το HotXLS εφαρμόζει τους ίδιους κανόνες που χρησιμοποιεί η μηχανή τύπων για αναφορές μεταξύ φύλλων, οπότε αν ένας σύνδεσμος δουλεύει σε έναν τύπο φύλλου εργασίας, τα εισαγωγικά του θα δουλέψουν και εδώ. Δώστε του ένα όνομα με κενό χωρίς εισαγωγικά και παίρνετε τον ίδιο σιωπηλό νεκρό σύνδεσμο για τον οποίο προειδοποιούσε η εισαγωγή
Τα σχόλια και οι υπερσύνδεσμοι είναι τα σημεία ενός δημιουργημένου βιβλίου εργασίας πάνω στα οποία οι αναθεωρητές ενεργούν χωρίς δεύτερη ματιά, κάτι που εξηγεί ακριβώς γιατί ένας στόχος που δεν οδηγεί πουθενά προκαλεί πραγματική ζημιά προτού το προσέξει κανείς. Χτίστε το πέρασμα επικύρωσης μία φορά, τρέξτε το σε κάθε βιβλίο εργασίας πριν αποσταλεί, και η ροή αναθεώρησης παραμένει ακέραιη σε μετονομασίες και μετατροπές. Η πλήρης επιφάνεια API και για τις δύο προσόψεις, XLS και XLSX, είναι τεκμηριωμένη στη σελίδα προϊόντος HotXLS Delphi Component