Hast Du zufällig Spalten, bei denen Visible auf false gesetzt ist?
Eventuell fallen die bei der Zählung ja raus, weshalb dann die erwartete Spaltenzahl und die tatsächlich gegebene Spaltenzahl nicht so ganz zusammenpassen.
Vergleiche doch bitte mal in DBGrid_TraDrawColumnCell die Inhalte von DataCol und Column.Field.FieldNo. Passt das "irgendwie" zusammen? Bei DataCol würde ich die Spaltennummer von links bei 0 beginnend gezählt erwarten, bei Column.Field.FieldNo die Position der Spalte in der
Query.
Wenn ich Deine bisherigen Erläuterungen richtig interpretiere, werden wohl 14 Spalten (0..13) angezeigt. Wenn im ShowMessage dann wieder bei 0 begonnen wird, heißt das, dass die Routine bereits die nächsten Zeile darstellt. Eventuell änderst Du Dein
ShowMessage(IntTostr(DataCol) + ' ');
mal in
ShowMessage(IntTostr(DataCol) + Column.Field.AsString);
, vielleicht kannst Du damit etwas genauer nachvollziehen, was da gerade passiert.