Direkter Zugriff Felder

Hallo,

ich möchte per C# Script direkt auf Datenbankfelder zugreifen. Kann mir jemand sagen, wo ich dazu in der Dokumentation etwas finde? Bin nicht fündig geworden.

Viele Grüße und ein schönes Wochenende!

Sie finden hier einige Beispiele:

…\cRM11\Scripts\Examples\C#Script\

Die Programmierreferenz (SDK Dokumentation), die als PDF installiert wurde, die ist Ihnen bekannt, richtig? :nerd_face:

Sonst einfach nochmal hier melden. :slight_smile:

Vielen Dank! Die Programmierreferenz ist mir bekannt und sehr hilfreich. Ich habe bislang immer die oCurrentInputForm.SetContentsByName Methode benutzt. Aber den direkten Zugriff auf Felder der Datenbanktabellen unabhängig davon, wo ich mich gerade in Combit befinde, ist mir noch nicht klar.

Der Grundablauf für einen Zugriff auf Datensatzfelder unabhängig von etwaigen gerade dargestellten Datensätzen läuft grundsätzlich wie folgt:

  1. ViewConfig für die gewünschte Zielansicht besorgen
  2. per ViewConfig.CreateRecordSet ein (nicht-visuelles) RecordSet Objekt dafür erzeugen
  3. per RecordSet.SetFilter… Methoden den/die gewünschten Treffer filtern (best-practice für Ergebnisabfrage siehe Kapitel 7.1)
  4. nach dem allerersten MoveFirst (siehe Kapitel 7.1) per RecordSet.CurrentRecord ein Record Objekt besorgen
  5. per Record.GetContentsValueByName und andere Record.GetContents… Methoden auf die Felder zugreifen
  6. ggf. eine Schleife starten, solange RecordSet.MoveNext true liefert, und durch alle weiteren Treffer-Datensätze laufen (Record Objekt muss NICHT neu zugewiesen werden, das Objekt „rutscht“ jeweils automatisch auf den jeweiligen per MoveNext angesteuerten Datensatz), weiter mit Schritt 5.
  7. Alle Objekte in „spiegelbildlicher“ Reihenfolge der Erzeugung freigeben

Der Schreibzugriff auf Felder eines Records erfolgt mit

  1. Record.Lock,
  2. Record.SetContents…,
  3. Record.Save,
  4. Record.Unlock.

Fehlerhandling mindestens bei CreateRecordSet, SetFilter, Lock und Save sind natürlich essentiell wichtig, zum Beispiel könnten aufgrund eingeschränkter Benutzerrechte hier die Aufrufe u.U. (korrekterweise) fehlschlagen und müssen vom Script entsprechend gewürdigt werden.

Dies soweit in aller Kürze. :sweat_smile:

Existiert hier ein Beispiel in C#, was Sie mir zur Verfügung stellen könnten? Ich würde gerne die Ansicht wechseln, aus der neuen Ansicht Daten kopieren und diese dann wieder schließen.

Nutzen Sie gerne das nachfolgende Beispiel. Mein Use-Case war dabei alle Namen der Ansprechpartner in eine kommaseparierte Liste in ein Feld in den aktuell angezeigten Firmen-Datensatz zu schreiben - das Script basiert auf einer combit_Large-Solution des cRM11.

// <!--#pragma debugmode-->
// <!--#pragma forcelogging-->
// <!--#include ref="System.Windows.Forms"-->
// <!--#include using="System.Windows.Forms"-->
// <!--#include ref="mscorlib.dll"-->
// <!--#include using="System.Collections.Generic"-->

#region Visual Studio only
using System.Collections.Generic;
using System.Windows.Forms;
using combit.cRM.COM;

namespace Visual_Studio_Projekt 
{ 
    class Template
    {
        static cRMApplication cRM = new cRMApplication(EApplicationStartType.GetActiveobject);
        #endregion Visual Studio only
        //-------------------------------------------------------------------------------------------------------
        //>> C# Script Code ab hier:

        public static void Main() 
        {
            // 1. Auslesen der ID des aktuell angezeigten Datensatzes (am Beispiel in der Firmen-Ansicht einer Large-Solution)
            Record currentRecord = cRM.CurrentProject.ActiveViews.ActiveView.CurrentRecordSet.CurrentRecord;
            string companyId = currentRecord.GetContentsByName("ID");

            // 2. Erstellen eines neuen RecordSets für die Ansicht Kontakte mit dem Ziel alle Datensätze anzuzeigen, die Ansprechpartner der Firma aus Schritt 1 sind
            string viewName = "Kontakte";
            ViewConfig viewConfigKontakte = cRM.CurrentProject.ViewConfigs.ItemByName(viewName);
            RecordSet recordSetKontakte = viewConfigKontakte.CreateRecordSet();
            List<string> listNamen = new List<string>();

            // 3. Filter auf alle Ansprechpartner der Firma
            if (recordSetKontakte.SetFilter("\"Kontakte\".\"CompanyID\" = " + companyId))
            {
                // 4. Gibt es Datensätze, die Ansprechpartner der dargestellten Firma sind?
                if (recordSetKontakte.MoveFirst())
                {
                    Record recordKontakt;

                    // Gibt es mehr als einen Datensatz?
                    if (recordSetKontakte.HasMultipleRecords)
                    {
                        // Durchlaufe alle Datensätze und füge die Informationen zu einer Liste hinzu
                        do
                        {
                            recordKontakt = recordSetKontakte.CurrentRecord;
                            listNamen.Add(recordKontakt.GetContentsByName("Name"));

                        } while (recordSetKontakte.MoveNext());
                    }
                    else
                    {
                        // Ansonsten nehme den ersten und einzigen Datensatz und lies den Namen des Ansprechpartners aus
                        recordKontakt = recordSetKontakte.CurrentRecord;
                        listNamen.Add(recordKontakt.GetContentsByName("Name"));
                    }
                }
                else
                {
                    cRM.DialogMessageBox("Der aktuelle Firmen-Datensatz hat keine Ansprechpartner.", "Keine Ansprechpartner", 0);
                }
            }

            // Sperre den angezeigten Firmen-Datensatz zur Bearbeitung
            if (currentRecord.Lock())
            {
                // Setze den ausgelesenen Inhalt aller Ansprechpartner in das Feld \"ListeAnsprechpartner\"
                currentRecord.SetContentsByName("ListeAnsprechpartner", string.Join(",", listNamen));
                
                // Speichere den Datensatz
                if (currentRecord.Save())
                {
                    cRM.DialogMessageBox("Es konnten Informationen von den Ansprechpartnern ausgelesen werden - es war jedoch nicht möglich das Feld \"ListeAnsprechpartner\" zu befüllen und den Firmen-Datensatz abzuspeichern.", "Kein Speichern möglich", 0);
                }

                // Gebe den Datensatz zur Bearbeitung frei
                currentRecord.Unlock();
            }
            else
            {
                if (currentRecord.Editable == false)
                {
                    cRM.DialogMessageBox("Der Datensatz ist für den aktuell angemeldeten Benutzer nicht bearbeitbar. Bitte wenden Sie sich an den Administrator.", "Keine Bearbeitbarkeit", 0);
                }
            }
        }
       
        //<< C# Script Code bis hier
        //-------------------------------------------------------------------------------------------------------
#region Visual Studio only
    }
}
#endregion Visual Studio only

Die Codebasis des Scripts kam aus dem nachfolgenden Knowledgebase-Artikel:

C# Scripting mit Microsoft Visual Studio - Knowledgebase - combit CRM Forum

1 „Gefällt mir“

Hallo,

ich habe ein Problem mit dem Filter. Ich möchte die ID der Ansicht „Kontakte“ mit der KontaktID aus der Ansicht „Belege“ vergleichen. Über KontaktID - ID wurde die Relation erstellt. In den beiden Ansichten in Combit kann ich es auch problemlos filtern. Die KontaktID im Feld ID in der Ansicht Kontakte eingegeben liefert das richtige Ergebnis.

Im Skript springt er jedoch immer in den Else-Zweig. Ich habe einen Screenshot mit der Ausgabe vom Debug gemacht. So langsam bin ich am verzweifeln.
Der Filter ist wie im Beispiel unter

// 3. Filter auf den entsprechenden Kontakt setzen, falls dieser exisitert

zu finden:

Schneller Tipp: Die KontaktID muss im Filterausdruck (bei MSSQL) noch einen 0x Präfix vorangestellt bekommen:

if (recordSetKontakte.SetFilter("\"Kontakte\".\"ID\" = 0x" + KontaktID))

Eventuell löst das schon das Problem. Ansonsten in Debwin gucken, welcher Fehler denn dort ausgespuckt wird.

Der schnelle Tipp hat leider nicht funktioniert. Aber vielen Dank für die schnelle Antwort! Die ausgabe von Debwin ist folgende:

▪;1000;24.01.2023 21:19:27.967;4;LL.Generic;F30;100:2=cRM♦101:1=0;!!! Error (0x00001008): 42S22 Der mehrteilige Bezeichner 'Kontakte.ID' konnte nicht gebunden werden., ErrPos=-1 
SQL command:

▪;1000;24.01.2023 21:19:27.967;1;LL.Generic;F30;100:2=cRM♦101:1=0;SELECT "Contacts"."ID","Contacts"."CompanyID","Contacts"."Salutation","Contacts"."Title","Contacts"."SalutationLetter","Contacts"."Name","Contacts"."NamePronunciation","Contacts"."Firstname","Contacts"."MatchCode","Contacts"."Position","Contacts"."Department","Contacts"."Phone","Contacts"."Phone2","Contacts"."MobilePhone","Contacts"."Fax","Contacts"."Email","Contacts"."Email2","Contacts"."InstantMessagingProvider","Contacts"."InstantMessaging","Contacts"."Facebook","Contacts"."Twitter","Contacts"."XING","Contacts"."ComPreference","Contacts"."Language","Contacts"."CustomerNo","Contacts"."AccountMngr","Contacts"."SalesArea","Contacts"."BusinessRelation","Contacts"."LeadSource","Contacts"."MainContact","Contacts"."PhotoType","Contacts"."Country_Private","Contacts"."ZIP_Private","Contacts"."City_Private","Contacts"."Street_Private","Contacts"."ZIPPOBox_Private","Contacts"."POBox_Private","Contacts"."MobilePhone_Private","Contacts"."MailingAddress","Contacts"."Partner_Salutation","Contacts"."Partner_Title","Contacts"."Partner_SalutationLetter","Contacts"."Partner_Name","Contacts"."Partner_Firstname","Contacts"."Partner_MailingAddress","Contacts"."Birthday","Contacts"."ZodiacSign","Contacts"."Birthplace","Contacts"."NativeCountry","Contacts"."Nationality","Contacts"."MaritalStatus","Contacts"."Gender","Contacts"."Interests","Contacts"."Category","Contacts"."Bank","Contacts"."IBAN","Contacts"."BIC","Contacts"."CreditCard","Contacts"."CreditCardNo","Contacts"."CC_EXP_M","Contacts"."CC_EXP_Y","Contacts"."PaymentTerm","Contacts"."Newsletter","Contacts"."LPersCont","Contacts"."UserDefined1","Contacts"."UserDefined2","Contacts"."UserDefined3","Contacts"."UserDefined4","Contacts"."UserDefined5","Contacts"."CreatedOn","Contacts"."CreatedBy","Contacts"."ModifiedOn","Contacts"."ModifiedBy","Contacts"."Deactivated","Contacts"."DeactivatedOn","Contacts"."Z_Import_PK","Contacts"."Z_Import_FK","Contacts"."Mediacode","Contacts"."Katalog","Contacts"."Katalog2","Contacts"."Katalog3","Contacts"."Katalog4","Contacts"."Katalog5","Cont...

Die Tabelle (nicht: Ansicht) heißt vmtl „Contacts“ statt „Kontakte“, dementsprechend müsste es Contacts.ID (entsprechend mit den doppelten Anführungszeichen präpariert) heißen. Das 0x braucht es zusätzlich.

Da lag der Hund begraben. Ich hatte es zuvor zwar mit „Contacts“ probiert, aber eben ohne 0x

Jetzt geht es. Vielen Dank!!! Bin halb wahnsinnig geworden…

1 „Gefällt mir“

Sie und die stillen Mitleser:innen können sich unter diesem Aspekt auf die Version 12 freuen. Dort wird man sich jeden Filter, der im Filterassistent oder im Filter-Allgemein Dialog zusammengeklickt wurde, direkt für Scripte als fertig komponierte Stringkonstante sich besorgen können:

(Natürlich würden Sie dann in Ihrem Fall die dann feste Beispiel-GUID an der Stelle durch Ihre Variable noch „patchen“ müssen, aber zumindest den Grundstock des SQL-Ausdrucks zu haben, ist schon extrem praktisch.)

2 „Gefällt mir“