TescoExpress
TescoExpress

Reputation: 55

Can't get the desired record from a table

I have made a function that would generate a new ID for a record in a database.

It does this by simply getting what the ID for the previous record is and then moving it one letter forward. For example, if the previous ID is AAA, the new ID would be AAB and so on.

The way I would get the previous ID is by counting the number of rows in the table and then using that number to get the last record in the table. The reason I am taking away 1, is because the row counter is not 0 indexed but the number of records is. So in a table with 50 records, the last record would record 49.

The problem is that this function only works for 1 record. So only the firstly generated ID will move forward, the rest will be the exact same as the second. For example, this is what it would look like.

0 - AAA, 1 – AAB, 2 – AAB, 3 – AAB….

// Generate codes in order
    public string StrGenerateSequentialCode(string StrTableName)
    {

        // Get the places for the counters from the previous code
        AccessTable ObjStoreCode = new AccessTable();
        ObjStoreCode.SelectTable(StrTableName);

        string StrPreviousID = "";

        StrPreviousID = ObjStoreCode.StrGetRow(ObjStoreCode.IntGetRowCount() - 1, 0);

Here is the rest of the code for the function.

 char[] ArrCollection = new char[36] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        int[] ArrPreviousIDSpace = new int[11]; // the number if chars for this code is fixed to 11

        for (int i = 0; i < ArrPreviousIDSpace.Length; i++)
        {
            for (int j = 0; j < ArrCollection.Length; j++)
            {
                if (ArrCollection[j] != StrPreviousID[i])
                {
                    ArrPreviousIDSpace[i]++;
                }
                else
                {
                    break;
                }
            }
        }


        // Now generate a code with each character carrying on from the last
        string StrCode = "";


        /* Add one to the last parts position until it reaches 27, 
         * when it does set its position to 0 and then add one to the second last parts
           position and repeat the process for the third last part...*/

        int A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0;

        // Make the starting points for the char selecters the 
        A = ArrPreviousIDSpace[0];
        B = ArrPreviousIDSpace[1];
        C = ArrPreviousIDSpace[2];
        D = ArrPreviousIDSpace[3];
        E = ArrPreviousIDSpace[4];
        F = ArrPreviousIDSpace[5];
        G = ArrPreviousIDSpace[6];
        H = ArrPreviousIDSpace[7];
        I = ArrPreviousIDSpace[8];
        J = ArrPreviousIDSpace[9];
        K = ArrPreviousIDSpace[10];

        // Turn the clock
        K++;
        if (K == ArrCollection.Length)
        {
            K = 0;

            J++;
        }
        if (J == ArrCollection.Length)
        {
            J = 0;

            I++;
        }
        if (I == ArrCollection.Length)
        {
            I = 0;

            H++;
        }
        if (H == ArrCollection.Length)
        {
            H = 0;

            G++;
        }
        if (G == ArrCollection.Length)
        {
            G = 0;

            F++;
        }
        if (F == ArrCollection.Length)
        {
            F = 0;

            E++;
        }
        if (E == ArrCollection.Length)
        {
            E = 0;

            D++;
        }
        if (D == ArrCollection.Length)
        {
            D = 0;

            C++;
        }
        if (C == ArrCollection.Length)
        {
            C = 0;

            B++;
        }
        if (B == ArrCollection.Length)
        {
            B = 0;

            A++;
        }
        // Combine the chars to make a final password
        StrCode = ArrCollection[A].ToString() + ArrCollection[B].ToString() + ArrCollection[C].ToString() + ArrCollection[D].ToString() + ArrCollection[E].ToString() + ArrCollection[F].ToString() + ArrCollection[G].ToString() + ArrCollection[H].ToString() + ArrCollection[I].ToString() + ArrCollection[J].ToString() + ArrCollection[K].ToString();
        return StrCode;

Here is the function that gets the record from the table.

public string StrGetRow(int IntSelectedRow = 0, int IntSelectedColumn = 0)
    {
        string StrRequesedRow = "";



        // This if statement will check whether or not the selected coloumns or rows are larger than the amount available
        if (IntSelectedRow < ObjDataSet.Tables[0].Rows.Count & IntSelectedColumn < ObjDataSet.Tables[0].Columns.Count)
        {
            // Make the table the data row origianates from the table on the dataset 
            DataRow = ObjDataSet.Tables[0].Rows[IntSelectedRow];
            // This will store the data in the string  'StrRequestedRow
            StrRequesedRow = DataRow.ItemArray.GetValue(IntSelectedColumn).ToString();
        }
        else
        {
            StrRequesedRow = "NO MORE RECORDS";
        }

        return StrRequesedRow;
    }

Upvotes: 0

Views: 66

Answers (1)

Filip Cordas
Filip Cordas

Reputation: 2561

If I remember my modular calculus your algorithm should be something like this

 public static string NumberToString(int number, int length,char[] allChars)
        {
            var remain = number;
            var result = "";
            var total = allChars.Length;
            while (remain >= total)
            {
                result = allChars[remain % total]+result;

                remain = (int)Math.Floor(remain * 1.0 / total);
            }
            result = allChars[remain]+result;
            return result.PadLeft(length, allChars[0]);
        }

This can be optimized but its simple. You used it like this.

static void Main(string[] args)
        {

            char[] allChars = { 'A', 'B', 'C', 'D' };
            var count = 0;
            Console.WriteLine(NumberToString(count,3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(++count, 3, allChars));
            Console.WriteLine(NumberToString(30, 3, allChars));
            Console.WriteLine(NumberToString(63, 3, allChars));


            Console.WriteLine("Done");
            Console.ReadLine();
        }

Just use the count of rows and use what ever length and character set. But don't say I didn't warn you about concurrency. You will have to lock the table during the time you read the count of rows till the time you insert the new row. Because if someone inserts a new row in that time you will get a collision of ids.

Upvotes: 1

Related Questions