Sheet set database giving me a null reference exception

DKollarJ8NUG
Participant

Sheet set database giving me a null reference exception

DKollarJ8NUG
Participant
Participant

Ok, I know this is another null reference question, but I've checked the forums and google and can't come up with a solution to my particular problem.

 

I have a function that loops through all of the sheets in a sheet set and updates the description of each. When I lock the database to make the changes to the description I have no problem. When I check the lock status of the database after the LockDB() method it says Locked_Local. Everything looks fine until after I make the change to the description and try to unlock the database and commit my changes. When the database.UnlockDb() statement executes I get a null reference exception. It makes no sense as I'm not changing the database.

 

What is confusing to me is I have another command that modifies the sheet properties in a similar way and that command doesn't have any issues locking and unlocking the database. I am getting the database in the same manner but for some reason this method doesn't work.

 

What am I doing wrong?

 

I have created a couple of helper functions to pull sheets from the sheet set manager and to lock/unlock the database. All of my code is below.

 

 

 

private static bool LockDatabase(AcSmDatabase database, bool lockFlag)
{
    bool dbLock = false;
    if (lockFlag == true && database.GetLockStatus() == AcSmLockStatus.AcSmLockStatus_UnLocked)
    {
        database.LockDb(database);
        dbLock = true;
    }
    if (lockFlag == false && database.GetLockStatus() == AcSmLockStatus.AcSmLockStatus_Locked_Local)
    {
        database.UnlockDb(database, true); // This is where I get the exception
        dbLock = true;
    }
    return dbLock;
}
public static void Test()
{
    try
    {
        Document doc = acApp.DocumentManager.MdiActiveDocument;
        using (Transaction tran = doc.TransactionManager.StartTransaction())
        {

            string description = "\n";
            List<AcSmSheet> sheets = GetSheets();
            foreach (AcSmSheet sheet in sheets)
            {
                AcSmDatabase database = sheet.GetDatabase();
                if (LockDatabase(database, true) == true)
                {
                    AcSmCustomPropertyValue value = GetSheetCustomValue(sheet, "SheetTitle1");
                    description = description + " " + value.GetValue().ToString();
                    value.Clear();

                    value = GetSheetCustomValue(sheet, "SheetTitle2");
                    description = description + " " + value.GetValue().ToString();
                    value.Clear();

                    value = GetSheetCustomValue(sheet, "SheetTitle3");
                    description = description + " " + value.GetValue().ToString();
                    value.Clear();

                    value = GetSheetCustomValue(sheet, "SheetTitle4");
                    description = description + " " + value.GetValue().ToString();
                    value.Clear();

                    doc.Editor.WriteMessage(description);
                    sheet.SetDesc(description);
                    description = "\n";

                    LockDatabase(database, false);
                }
            }
            tran.Commit();
        }
    }
    catch (System.Exception e)
    {
        acApp.ShowAlertDialog(e.Message);
    }
}

 

 

 

0 Likes
Reply
Accepted solutions (1)
372 Views
5 Replies
Replies (5)

tatetopggg
Observer
Observer

@DKollarJ8NUG wrote:

Ok, I know this is another null reference question, but I've checked the forums and google and can't come up with a solution to my particular problem.

 

I have a function that loops through all of the sheets in a sheet set and updates the description of each. When I lock the database to make the changes to the description I have no problem. When I check the lock status of the database after the LockDB() method it says Locked_Local. Everything looks fine until after I make the change to the description and try to unlock the database and commit my changes. When the database.UnlockDb() statement executes I get a null reference exception. It makes no sense as I'm not changing the database.

 

What is confusing to me is I have another command that modifies the sheet properties in a similar way and that command doesn't have any issues locking and unlocking the database. I am getting the database in the same manner but for some reason this method doesn't work.

 

What am I doing wrong?

 

I have created a couple of helper functions to pull sheets from the sheet set manager and to lock/unlock the database. All of my code is below.

 

 

 

 

private static bool LockDatabase(AcSmDatabase database, bool lockFlag)
{
    bool dbLock = false;
    if (lockFlag == true && database.GetLockStatus() == AcSmLockStatus.AcSmLockStatus_UnLocked)
    {
        database.LockDb(database);
        dbLock = true;
    }
    if (lockFlag == false && database.GetLockStatus() == AcSmLockStatus.AcSmLockStatus_Locked_Local)
    {
        database.UnlockDb(database, true); // This is where I get the exception
        dbLock = true;
    }
    return dbLock;
}
public static void Test()
{
    try
    {
        Document doc = acApp.DocumentManager.MdiActiveDocument;
        using (Transaction tran = doc.TransactionManager.StartTransaction())
        {

            string description = "\n";
            List<AcSmSheet> sheets = GetSheets();
            foreach (AcSmSheet sheet in sheets)
            {
                AcSmDatabase database = sheet.GetDatabase();
                if (LockDatabase(database, true) == true)
                {
                    AcSmCustomPropertyValue value = GetSheetCustomValue(sheet, "SheetTitle1");
                    description = description + " " + value.GetValue().ToString();
                    value.Clear();

                    value = GetSheetCustomValue(sheet, "SheetTitle2");
                    description = description + " " + value.GetValue().ToString();
                    value.Clear();

                    value = GetSheetCustomValue(sheet, "SheetTitle3");
                    description = description + " " + value.GetValue().ToString();
                    value.Clear();

                    value = GetSheetCustomValue(sheet, "SheetTitle4");
                    description = description + " " + value.GetValue().ToString();
                    value.Clear();

                    doc.Editor.WriteMessage(description);
                    sheet.SetDesc(description);
                    description = "\n";

                    LockDatabase(database, false);
                }
            }
            tran.Commit();
        }
    }
    catch (System.Exception e)
    {
        acApp.ShowAlertDialog(e.Message);
    }
}

 

 

 

 


The null reference exception in your code likely occurs because the database object becomes null or loses its reference at some point between locking and unlocking the database. Here’s a potential solution:

Make sure that the database object remains valid and that it is properly initialized before attempting to unlock it. One common reason for this issue is that the sheet.GetDatabase() method may return a null value, especially if the sheet’s database is not correctly linked or initialized.

 

To address this, add a check to ensure that database is not null before calling the LockDatabase method. You can modify your code like this:

foreach (AcSmSheet sheet in sheets)
{
AcSmDatabase database = sheet.GetDatabase();
if (database != null && LockDatabase(database, true))
{
// Your existing code to modify descriptions
// ...

LockDatabase(database, false); // Unlock safely
}
else
{
doc.Editor.WriteMessage("Error: Database reference is null.\n");
}
}

0 Likes

norman.yuan
Mentor
Mentor

Since you did not show the code of GetSheets() method, so I have no idea where the sheets returned by this method are from: from a single *.dst file (this the same SheetSet/sheet database, or from multiple *.dst files (i.e. diffrent database)? But I assume it is from the same sheet database, opened against single *.dst file.

 

If my assumption is correct, you do not need to lock/unlock the database when update each sheet. You only lock the database before the "foreach..." loop and unlock it when all are done, instead of repeatedly locking/unlocking

 

The pseudo code would be like:

 

AcSmDatabase database = [TheAcSmManager].OpenDatabase(...);

database.LockDb(database);

try

{

  List<AcSmSheet> sheets=GetSheets(database);

  foreach (var sheet in sheets)

  {

     // update sheet properties

  }

}

finally

{

  database.UnlockDb(database, true);

  [TheAcShManager].Close(database);

}

 

Also, there is no need to start a Transaction: you do not change anything with the drawing database. The change made to each sheet will only take effect when UnlockDb() is called and the second argument is set to TRUE.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes

DKollarJ8NUG
Participant
Participant

I made the changes you suggested by opening the dst database directly using the AcSmSheetSetMgr.OpenDatabase() method and moving the lock and unlock functions outside the loop. I added a null check as well. I'm still getting the null reference exception.

0 Likes

DKollarJ8NUG
Participant
Participant
Accepted solution

I commented out every line in the loop except the first. As I was working on it, I went line by line uncommenting each until I got the error. I don't understand how or why, but the line value.Clear() was causing the error. As soon as I removed those lines, everything worked as expected without error.

0 Likes

ructiik
Community Visitor
Community Visitor

have you tried to use chatgpt? 

also btw i know its about something else but ive been enjoying reading some gaming guides when i'm bored and that is really entertaining

0 Likes