Hätte ich bloß was anständiges gelernt...

Mittwoch, 24.8.2022, 09:33 > daMax

Es gibt so Tage, da weißt du, dass der Rest der Woche schlimm wird. Im Moment z.B. schlage ich mich mit Code von jemandem herum, der keine Ahnung vom Programmieren hatte, dafür aber auch zu stolz zum Fragen war und sich statt dessen munter bei StackOverflow mit Codeschnippseln bedient hat, die er dann hundertfach copy-pastete. All over the place.

Die so entstandene Software soll Daten in einer Accessdatenbank verwalten. Das fragile Konstrukt lief jetzt viele Jahre lang mehr oder weniger okayish und jedes Mal, wenn ich irgendwas darin fummeln musste, hatte ich halt mal einen schlechten Tag. So weit, so unspannend.

Nun aber hat der Kunde nicht nur ein neues Laptop, sondern auch von Office 20xx umgestellt auf Office 365. Und jetzt crasht die Software mit den lustigsten Fehlermeldungen, von denen mir persönlich ja "Corrupted heap space" am Besten gefällt, aber eben auch die größten Kopfschmerzen bereitet.

Dieses Stückchen Code zum Beispiel:

''' <summary>
''' Modify note version of selected ID from the table Versions
''' </summary>
''' <returns>
''' SQL command
''' </returns>
''' <remarks>
''' </remarks>
Public Function Update_Note_Version_To_Max(ByVal lNoteVersionID As Long,
                                         ByVal lVersion As Long,
                                         ByVal cn As OleDbConnection) As OleDbCommand

        'Instantiate the SQL Statement
        Dim SqlString As String = "UPDATE " & tbl_Note_Versions_Name &
                          " SET " & col_Versions_Version & "= ? " &
                          "WHERE [" & col_Versions_ID & "] = " & lNoteVersionID & ""

        Dim cmd As New OleDbCommand(SqlString, cn)
        cmd.CommandType = CommandType.Text

        'Define Parameters
        cmd.Parameters.AddWithValue(col_Versions_Version, lVersion)

        'Return the result of the query
        Return cmd

End Function

erzeugt einen OleDbCommand, der später dann per cmd.ExecuteNonQuery() ausgeführt wird. Das alleine ist schon ziemlich kaputt, weil natürlich die Referenz auf diesen Command nie wirklich freigegeben wird, aber das sei jetzt mal dahin gestellt. .NET ist ja clever, und so...

Bei mir auf dem PC läuft das alles durch, beim Kunden jedoch fliegt eine "Too few parameters"-Exception. Wenn ich nun lVersion von einem long in ein UInteger verändere, funktioniert der Scheiß. Warum? Keine Ahnung, ey! Ist aber konstant. Überall, wo der Scheiß crasht, kann man longs in UIntegers umwandeln und alles tut. Das ist "nur" lästig, weil solche sinnlosen Helferfunktionen ü-ber-all vervielfacht wurden.

So richtig schlimm wird es allerdings dann bei folgendem Code. Achtung, festhalten, Einrückung wie im Original, leider ist der Textbereich hier im Blog zu schmal, deshalb kommen ein paar Zeilenumbrüche dazu, aber das macht bei diesem Schrottkonstrukt auch nichts mehr. Aufm Handy brauchste das aber gar nicht erst zu lesen:

Dim query_notes = From note In query_activities_group
  Group Join note_type In tbl_Note_Types.AsEnumerable()
  On note.type Equals note_type.Field(Of Integer)(col_Note_Types_ID)
  Into list2 = Group
  From note_type In list2.DefaultIfEmpty
  Group Join note_version In tbl_Note_Versions.AsEnumerable()
  On note.id Equals note_version.Field(Of Integer)(col_Versions_Note_ID)
  Into list3 = Group
  From note_version In list3.DefaultIfEmpty
  Group Join status In tbl_Note_Version_Statuses.AsEnumerable()
  On note_version.Field(Of Integer)(col_Versions_Version_Status_ID) Equals status.Field(Of Integer)(col_Version_Statuses_ID)
  Into list4 = Group
  From status In list4.DefaultIfEmpty
  Select New With {
  .fullnumber = If(note.fullnumber Is Nothing, "", note.fullnumber),
  .title = If(note.title Is Nothing, "", note.title),
  .chapter = If(note.fullnumber.contains("."), note.fullnumber.Substring(0, InStrRev(note.fullnumber, ".") - 1), ""),
  .activity = If(note.activity Is Nothing, "", note.activity),
  .type = If(note_type Is Nothing, "", note_type.Field(Of String)(col_Note_Types_Type)),
  .sub_type = If(note_type Is Nothing, "", note_type.Field(Of String)(col_Note_Types_SubType)),
  .type_link = If(note_type Is Nothing, "", note_type.Field(Of String)(col_Note_Types_Link)),
  .version_id = If(note_version Is Nothing, 0, note_version.Field(Of Integer)(col_Versions_ID)),
  .note_ID = If(note_version Is Nothing, -1, note_version.Field(Of Integer)(col_Notes_ID)),
  .note_version = If(note_version Is Nothing, 0, note_version.Field(Of Integer)(col_Versions_Version)),
  .body = If(note_version Is Nothing, "", note_version.Field(Of String)(col_Versions_Body)),
  .description = If(note_version Is Nothing, "", note_version.Field(Of String)(col_Versions_Description)),
  .ctm = If(note_version Is Nothing, False, note_version.Field(Of Boolean)(col_Versions_CtM)),
  .dtm = If(note_version Is Nothing, False, note_version.Field(Of Boolean)(col_Versions_DtM)),
  .status = If(status Is Nothing, "", status.Field(Of String)(col_Version_Statuses_Status)),
  .date_creation = note_version.Field(Of Date?)(col_Versions_Version_Creation_Date),
  .date_release = note_version.Field(Of Date?)(col_Versions_Version_Release_Date),
  .date_decommission = note_version.Field(Of Date?)(col_Versions_Version_Decommission_Date),
  .additionallogic = note.additionallogic,
  .mandatory = If(note_version Is Nothing, False, note_version.Field(Of Boolean)(col_Versions_Mandatory))
  }

Yo, dawg.

Ehrlich gesagt verstehe ich nicht mal, was dieses 4-fach verschachtelte Group-Join-Konstrukt tut. Geschweige denn habe ich eine Ahnung, wo ein "corrupted heap space" her kommt. Ich vermute, das wird was mit der Tatsache zu zun haben, dass Datenbank-Connection ständig munter durch die Gegend gereicht wird, aber sicher bin ich nicht. Vor allem kann ich den Rotz nicht bei mir aufm Rechner debuggen, weil es bei mir ja alles läuft. Statt dessen darf ich das per Zoom-Desktop-Sharing aufm Kundenrechner versuchen.

Das ist alles so sinnlos.

Solltet ihr mal mitbekommen, dass ein Mensch ohne die geringste Programmiererfahrung damit beauftragt wird, eine vollständige, halbwegs komplexe Software ganz alleine zu schreiben, zündet den Laden einfach gleich an. Denn die Wahrscheinlichkeit ist groß genug, dass diese Type längst über alle Berge ist, bis Feuer ausm Schacht kommt. Und dann steht ihr da. Wie ich heute. Und verzweifelt.