Results 1 to 19 of 19

Thread: How can I use a delimiter to filter data from field then display as bullet points

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Nov 2022
    Location
    Manitoba, Canada
    Posts
    152

    Question How can I use a delimiter to filter data from field then display as bullet points

    I'm trying to learn some database coding after being away for a while. I never was great at it and now I'm really struggling...

    I'm using Visual Studio 2019 and SQLite, programming in VB.

    What I need to achieve: Within my database table I have a handful of fields with one of those fields containing a bunch of different pieces of data (keywords). This data is separated by a semi-colon. I need to pull the data from that field, break the data up at the semi-colons and display those individual pieces of data (keywords) as text in bullet point form within a Label on my Form.

    Currently there is some other stuff going on as well, like populating a DataGridView from the same table using using a binding source and whatnot. I'm unsure how to filter through the data table (or if I even have to) in order to pluck the individual pieces of data from the field in question.

    What I think I understand: Please correct me if I am wrong...

    1. Structure a database connection (dbCon) by defining the SQLiteConnection path.
    2. Structure the data set (Adapter1) by defining my desired query table and data field(s).
    3. Develop an SQLiteDataAdapter (adCardsTable) which is acts as a bridge between the database and the dataset.
    4. Define a Data Table (dtCardsTable) which works essentially like RAM memory, independent from the database itself.
    5. Define a Binding Source (bsCardsTable) which is used to display the data into various objects, such as a DGV.

    Code:
    Imports System.Data.SQLite
    
    Public Class frmMain
    
        Private ReadOnly dbCon As New SQLiteConnection("Data Source=" & Application.StartupPath & "\CardsSample.db;" & "Version=3;New=False;Compressed=True;")
    
        Dim Adapter1 As String = ("SELECT ID, Deck, Name, KeyWords, KeyPhrases, Picture FROM Cards ORDER BY ID ASC")
    
        Private WithEvents adCardsTable As New SQLiteDataAdapter(Adapter1, dbCon)
    
        Private dtCardsTable As New DataTable
        Private bsCardsTable As New BindingSource

    6. Use the SQLiteDataAdapter (adCardsTable) to retrieve the data and place it into a Data Table (dtCardsTable), which functions sort of like RAM memory.
    7. Call to Set Up Bindings and then Call to Set Up The DGV
    Code:
        Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            adCardsTable.Fill(dtCardsTable)
    
            SetUpBindings()
            SetUpDataGridView()
    
        End Sub

    8. Bind the data table (dtCardsTable) to a binding source (bsCardsTable)
    9. Bind all of the Data Table (dtCardsTable) to a DataGridView (DGV_Database)
    10. Bind the data from the field "Name" to a label (lblCardName)
    11. Bind the data from the field "KeyWords" to a label (lblKeyWords)
    12. Bind the data from the field "KeyPhrases" to a label (lblKeyPhrases)
    13. Bind the data from the field "Picture" to a picture box (PictureBox)
    Code:
        Private Sub SetUpBindings()
    
            bsCardsTable.DataSource = dtCardsTable
    
            Me.DGV_Database.DataSource = bsCardsTable
            Me.lblCardName.DataBindings.Add("Text", bsCardsTable, "Name")
            Me.lblKeyWordsDB.DataBindings.Add("Text", bsCardsTable, "KeyWords")
            Me.lblKeyPhrasesDB.DataBindings.Add("Text", bsCardsTable, "KeyPhrases")
            Me.PictureBox.DataBindings.Add("Image", bsCardsTable, "Picture", True)
    
        End Sub

    14. Use the binding source (bsCardsTable) to set the data source for the Data Grid View (DGV_Database).
    15. Hide some of the columns of the DGV, showing only the two that I feel are required.
    16. Set the column width for those two columns and manipulate a few other DGV attributes.
    Code:
        Private Sub SetUpDataGridView()
    
            With Me.DGV_Database
                .DataSource = bsCardsTable
                .SelectionMode = DataGridViewSelectionMode.FullRowSelect
                .Columns("ID").Visible = True                  
                .Columns("Deck").Visible = False                   
                .Columns("Name").Visible = True                  
                .Columns("KeyWords").Visible = False              
                .Columns("KeyPhrases").Visible = False                                    
                .Columns("Picture").Visible = False                                         
                .AllowUserToAddRows = False                                                
                .RowHeadersVisible = False                                                  
                .ColumnHeadersVisible = False                                               
                .Columns(0).Width = 30
                .Columns(2).Width = 146
            End With
    
        End Sub

    So, that is what I have so far and it all functions flawlessly. I can highlight an item in the DGV and in turn it displays the appropriate data into the appropriate form objects. The corresponding picture is displayed into the picture box and likewise, the corresponding keywords are displayed in a label on the form. They are of course displayed as a paragraph of words that are separated by semi-colons. What I am looking to do is display these keywords as bullet points.

    It is my assumption that I need to pass the data through an Array (is that correct?) and filter the data from the field "KeyWords" using a semi-colon as a delimiter? Then I'll have to take each individual word that has been filtered and somehow create a bullet point and place that text next to it before going on to create another bullet point IF there is another keyword in the field.


    I have done my very best to explain my situation to the best of my limited capacity. Should anyone wish to look at my project for more clarity, I have made it downloadable here:
    http://www.degueldre-knives.com/Misc-Files/

    Thanks for any and all direction offered.
    Last edited by The_Hobbyist; Sep 27th, 2024 at 01:48 AM. Reason: Clarification

  2. #2
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,736

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Code:
    CREATE TABLE "cards" (
        "ID"    INTEGER,
        "Keywords"    TEXT,
        PRIMARY KEY("ID")
    )
    Code:
    INSERT INTO "main"."cards" ("ID", "Keywords") VALUES ('1', 'Text1;text2;text3;text4');
    INSERT INTO "main"."cards" ("ID", "Keywords") VALUES ('2', 'Othertext1;Othertext2;OtherText3');
    Code:
    WITH 
    RECURSIVE split(id,last,rest) AS (
    SELECT ID, '', Keywords FROM cards
    UNION ALL
    SELECT ID, 
    CASE WHEN instr(rest,';')>0 THEN
      substr(rest,1,instr(rest,';')-1)
    ELSE
      substr(rest,1) 
    END,
    CASE WHEN instr(rest,';')>0 THEN
      substr(rest,instr(rest,';')+1) 
    ELSE
      ''
    END
    FROM split WHERE rest<>'')
    SELECT ID, last As Keywords FROM split WHERE last<>''
    ORDER BY ID, lower(Keywords)
    Returns
    id Keywords
    1 Text1
    1 text2
    1 text3
    1 text4
    2 Othertext1
    2 Othertext2
    2 OtherText3

    EDIT: This smells of a "misdesign" of the Database or at least that table.
    There's usually no reason to keep delimited text in a single field, if you need it separated.
    Create a child-table "keywords" (or whatever name) with a Foreign Key pointing to the Primary Key of its Master-Table "Cards"

    EDIT2: Alternative Version of the Query (using IIF)
    Same Results
    Code:
    WITH 
    RECURSIVE split(id,last,rest) AS (
    SELECT ID, '', KeyWords FROM Cards
    UNION ALL
    SELECT ID, 
    IIF(instr(rest,';')>0,substr(rest,1,instr(rest,';')-1),substr(rest,1)),
    IIF(instr(rest,';')>0,substr(rest,instr(rest,';')+1) ,'')
    FROM split WHERE rest<>'')
    SELECT ID, last As KeyWords FROM split WHERE last<>''
    ORDER BY ID, lower(KeyWords)
    EDIT3: Variant 3, with only one place to define which Delimiter
    Code:
    WITH 
    DT(Delimiter) AS (VALUES(';')),
    split(id,last,rest) AS (
    SELECT ID, '', Keywords FROM Cards 
    UNION ALL
    SELECT ID, 
    IIF(instr(rest,Delimiter)>0,substr(rest,1,instr(rest,Delimiter)-1),substr(rest,1)),
    IIF(instr(rest,Delimiter)>0,substr(rest,instr(rest,Delimiter)+1) ,'')
    FROM split 
    INNER JOIN DT ON 1=1
    WHERE rest<>'')
    SELECT ID, last As SplitText FROM split WHERE last<>''
    ORDER BY ID, lower(SplitText)
    Last edited by Zvoni; Sep 27th, 2024 at 05:22 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Nov 2022
    Location
    Manitoba, Canada
    Posts
    152

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Thank you for this, Zvoni.

    Quote Originally Posted by Zvoni View Post
    EDIT: This smells of a "misdesign" of the Database or at least that table.
    There's usually no reason to keep delimited text in a single field, if you need it separated.
    Create a child-table "keywords" (or whatever name) with a Foreign Key pointing to the Primary Key of its Master-Table "Cards"
    Hmmm....... When I was last working with databases, I found that relational database structure and how to tie it all together and query it properly afterwards was challenging. Designing the roadmap and then utilizing it properly so to speak. With help and patience from this forum however, I seemed to manage. Now that it seems apparent that I was about to set out on the wrong foot here, I am going to go back and look at that past project in an effort to re-discover the proper way of doing this. Reading your statement above reminded me of how fundamental a proper database structure is to a smooth, efficiently run program. I believe you to be correct when you say "There's usually no reason to keep delimited text in a single field". For now, I am off to ponder my database structure.

    Thank you! I will surely be back with questions but in the meantime, I appreciate you.

  4. #4

    Thread Starter
    Addicted Member
    Join Date
    Nov 2022
    Location
    Manitoba, Canada
    Posts
    152

    Re: How can I use a delimiter to filter data from field then display as bullet points

    After an exhausting night of database research and then database re-structuring, I believe that I have a cleaner set of tables to work with. I am no longer utilizing a delimiter to separate data. As suggested, I have created a child table which is then linked to the primary table via a Foreign Key setup. OK.... So, my table structures look like this:

    Name:  Tables.jpg
Views: 122
Size:  67.7 KB

    Then through the following code I have been able connect to the database, query the tables, retrieve and view the desired data within some form objects (DataGridView, Label & PictureBox). I am having a different problem now but I'm unsure if I should start another thread on the forum or continue in this one? For now I will continue here.

    Problem 1: I am seeing a complete list of records for the entire database inside the DataGridView however, I would like to avoid seeing duplicates of the same card (based on the Card ID field). I believe this is happening because each card has multiple Key Words (fields) associated with it in the database and the DGV is displaying a record for each of those Key Words. How do I filter this to only show each individual Card just once?

    Problem 2: I don't know where to start when it comes to taking each of the Key Words associated with a certain Card and generating a bullet list and then displaying that list within a Label. The bullet list is to be populated solely by each key word associated with the card selected within the DGV.

    Below the code, I will share a screen shot of my project in its current state.

    Code:
    Imports System.Data.SQLite
    
    Public Class frmMain
    
        Private ReadOnly dbCon As New SQLiteConnection("Data Source=" & Application.StartupPath & "\CardsSample.db;" & "Version=3;New=False;Compressed=True;")
    
        Dim Adapter1 As String = ("SELECT
                                    Cards.ID, Cards.Deck, Cards.Name, Cards.KeyWordsID, Cards.Picture,
                                    KeyWords.KeyWords_ID, KeyWords.Word
                                    FROM KeyWords
                                    INNER JOIN Cards
                                    ON KeyWords.KeyWords_ID = Cards.KeyWordsID
                                    ORDER by Cards.ID")
    
        Private WithEvents adCardsTable As New SQLiteDataAdapter(Adapter1, dbCon)
    
        Private dtCardsTable As New DataTable
        Private bsCardsTable As New BindingSource
    
    
    
        Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            adCardsTable.Fill(dtCardsTable)
    
            SetUpBindings()
            SetUpDataGridView()
    
        End Sub
    
    
    
        Private Sub SetUpBindings()
    
            bsCardsTable.DataSource = dtCardsTable
    
            Me.DGV_Database.DataSource = bsCardsTable
            Me.lblCardName.DataBindings.Add("Text", bsCardsTable, "Name")
            Me.PictureBox.DataBindings.Add("Image", bsCardsTable, "Picture", True)
            Me.lblKeyWordsDB.DataBindings.Add("Text", bsCardsTable, "Word")
    
        End Sub
    
    
    
        Private Sub SetUpDataGridView()
    
            With Me.DGV_Database
                .DataSource = bsCardsTable
                .SelectionMode = DataGridViewSelectionMode.FullRowSelect 
                .Columns("ID").Visible = True                               
                .Columns("Deck").Visible = False                           
                .Columns("Name").Visible = True                            
                .Columns("KeyWordsID").Visible = False                     
                .Columns("Picture").Visible = False                         
                .Columns("KeyWords_ID").Visible = False                    
                .Columns("Word").Visible = False                            
                .AllowUserToAddRows = False                                 
                .RowHeadersVisible = False                                 
                .ColumnHeadersVisible = False                               
                .Columns(0).Width = 30
                .Columns(2).Width = 146
            End With
    
        End Sub
    
    
    
        Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
    
            Me.Close()
    
        End Sub
    
    End Class
    The below image shows The Emperor card being selected from the DGV which in turn displays the correct image in the picturebox, the correct name in the Label at the top and even one of the correct KeyWords all associated with The Emperor card. I need to eliminate the duplicate cards from the DGV though, meaning show just 1 Emperor card while creating a bullet list for the 5 different key words associated with that card.
    Name:  Screenshot_001.jpg
Views: 123
Size:  30.7 KB

    I'm looking forward to help and suggestions. Thank you.

  5. #5
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,736

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Wrong way around. The foreign key-column belongs in table keywords, and points to id of cards
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Nov 2022
    Location
    Manitoba, Canada
    Posts
    152

    Re: How can I use a delimiter to filter data from field then display as bullet points

    I'm sorry, I don`t understand. I thought that I had my database structured that way? The way I understand it, I have the foreign key-column in table KeyWords.KeyWords_ID and it points to Cards.KeyWordsID. Does this not tie the Cards.KeyWords data field to the KeyWords.KeyWords_ID data field? Here is a better screenshot of the database structure:

    Name:  Tables_002.jpg
Views: 88
Size:  12.6 KB

    My data table seems to retrieve all of the relevant data from across both tables. I then bind it to and display it in the DGV. With that said, I'm still unsure how to remove the duplicate card names from the DGV? Does this somehow tie into my foreign key mix up? I also wish to display all of the keywords in the label on the form. I'll attach a new screenshot which widens the DGV, better showing the data from both tables. The ID field in the DGV is from the Card table while I have the KeyWords_ID field hidden from view in the DGV.

    Name:  Screenshot_003.jpg
Views: 97
Size:  36.2 KB


    My complete code for this entire project is as follows:
    Code:
    Imports System.Data.SQLite
    
    Public Class frmMain
    
        Private ReadOnly dbCon As New SQLiteConnection("Data Source=" & Application.StartupPath & "\CardsSample.db;" & "Version=3;New=False;Compressed=True;")
    
        Dim Adapter1 As String = ("SELECT
                                    Cards.ID, Cards.Deck, Cards.Name, Cards.KeyWordsID, Cards.Picture,
                                    KeyWords.KeyWords_ID, KeyWords.Word
                                    FROM Cards
                                    JOIN KeyWords
                                    On Cards.KeyWordsID = KeyWords.KeyWords_ID
                                    ORDER by Cards.ID")
    
        Private WithEvents adCardsTable As New SQLiteDataAdapter(Adapter1, dbCon)
    
        Private dtCardsTable As New DataTable
        Private bsCardsTable As New BindingSource
    
    
    
        Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            adCardsTable.Fill(dtCardsTable)
    
            SetUpBindings()
            SetUpDataGridView()
    
        End Sub
    
    
    
        Private Sub SetUpBindings()
    
            bsCardsTable.DataSource = dtCardsTable
    
            Me.lblCardName.DataBindings.Add("Text", bsCardsTable, "Name")
            Me.PictureBox.DataBindings.Add("Image", bsCardsTable, "Picture", True)
            Me.lblKeyWordsDB.DataBindings.Add("Text", bsCardsTable, "Word")
    
        End Sub
    
    
    
        Private Sub SetUpDataGridView()
    
            With Me.DGV_Database
                .DataSource = bsCardsTable
                .DefaultCellStyle.Font = New Font("Tahoma", 9.75, FontStyle.Regular)
                .DefaultCellStyle.SelectionBackColor = Color.Pink
                .DefaultCellStyle.SelectionForeColor = Color.Red
                .SelectionMode = DataGridViewSelectionMode.FullRowSelect
                .Columns("ID").Visible = True
                .Columns("Deck").Visible = False
                .Columns("Name").Visible = True
                .Columns("KeyWordsID").Visible = False
                .Columns("Picture").Visible = False
                .Columns("KeyWords_ID").Visible = False
                .Columns("Word").Visible = True
                .AllowUserToAddRows = False
                .RowHeadersVisible = False
                '            .ColumnHeadersVisible = False          '<--- ADDS THE COLUMN HEADERS FOR FORUM POST CLARITY
                .Columns(0).Width = 25
                .Columns(2).Width = 115
                .Columns(6).Width = 145
            End With
    
        End Sub
    
    
    
        Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
    
            Me.Close()
    
        End Sub
    
    End Class
    Last edited by The_Hobbyist; Sep 30th, 2024 at 01:19 PM. Reason: Show first image

  7. #7
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,736

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Quote Originally Posted by The_Hobbyist View Post

    Name:  Tables.jpg
Views: 122
Size:  67.7 KB
    You have in "Cards" a Column "KeywordsID" which is a Foreign Key to "Keywords_ID" in "KEywords".
    Wrong. It has to be the other way around.

    You need a column "CardsID" in "Keywords" being a Foreign Key to "ID" in "Cards"

    You have a card called "Fool" (1 Card), which has multiple "Keywords" (n keywords) ("Childlike", "Innocent" etc.) --> "1:n" --> The "n" always points to the table which needs the Foreign Key, the "1" to which table that Foreign Key points to

    And i seem to see some other issues (Deck? Picture?)

    EDIT: Going by your Screenshot of your Form:
    You need two Queries:
    1) the first Query is for your ListBox on the Left representing the Cards.
    SELECT ID, Name FROM Cards
    2) The second Query, which gets executed INSIDE the OnClick, OnSelection, whatever Event there is if you click on a row of the Listbox
    SELECT Word FROM Keywords WHERE CardID=IDOfClickedCardInListBox
    And the result of that Query goes into your Label, or whatever control you have there for the Keywords.
    I would probably use a selfexpanding/shrinking ListBox in flat and "unclickable" Style (without Scrollbars).
    Basically a simulation of a multiline Label
    Last edited by Zvoni; Sep 30th, 2024 at 01:57 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  8. #8

    Thread Starter
    Addicted Member
    Join Date
    Nov 2022
    Location
    Manitoba, Canada
    Posts
    152

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Quote Originally Posted by Zvoni View Post
    You need a column "CardsID" in "Keywords" being a Foreign Key to "ID" in "Cards"
    I have changed a few things in the tables now. For example, I removed a field or two which I wasn't using at this time. They were reserved for later, once I got this code straightened out. For the sake of simplicity, I'll just include the relevant fields and have modified the tables to reflect that.

    Regarding the reply above, am I not doing what I am instructed to do here? ...Or is it still backwards? Looking at the screenshot below, the way I understand it, I currently have a CardsID field within my KeyWords table and that CardsID field is set as the foreign key which in turn is pointing to the ID field within the Cards table.

    Name:  Tables_003.jpg
Views: 87
Size:  9.8 KB
    Last edited by The_Hobbyist; Sep 30th, 2024 at 04:48 PM. Reason: Grammar

  9. #9
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,736

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Now it looks good.

    As i wrote above: You need 2 Queries (resp. 3 Queries)
    1) SELECT ID, Name FROM Cards ORDER BY Name
    Take the result from that and fill up that Grid on your left side

    After you click on an entry on left side grid,
    INSIDE the Click-Event (Or Selection-Event, no idea what you use) you have to grab the ID from its column (or from whereever)
    and execute the following 2 Queries
    2) SELECT Picture FROM Cards WHERE ID=?
    Set the Parameter for ID with that ID from the Column and grab the Picture
    Resulting RecordCount should be 1 --> Check for NON-NULL-Result of Picture

    3) SELECT Word FROM Keywords WHERE CardsID=?
    Set the Parameter for CardsID with the ID you grabbed from the Column
    Use that result to populate your Label (or whatever control you use) for your bulletpoints
    RecordCount can be anything


    It's the same for adding, changing, deleting Keywords:
    You FIRST have to select a Card (to get its ID)
    Adding a new Keyword
    INSERT INTO Keywords (cardsID, Word) VALUES(?,?)
    Set the 2 Parameters: First to the ID, second to the Textbox (or whatever)

    Changing a single Keyword doesn't work in your setup. You need a separate ID-Column in Keywords

    Deleting all Keywords (!!!!) --> You don't have a separate ID for each Keyword, so be careful with this
    DELETE FROM Keywords WHERE CardsID=?
    Set the Parameter for CardsID with the ID
    Last edited by Zvoni; Oct 1st, 2024 at 01:13 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  10. #10
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,736

    Re: How can I use a delimiter to filter data from field then display as bullet points

    btw: If you want to go back to your "original" concept (one Field with delimited Text)

    It would still be 2/3 Queries

    1) SELECT ID, Name FROM Cards ORDER BY Name
    Take the result from that and fill up that Grid on your left side

    After you click on an entry on left side grid,
    INSIDE the Click-Event (Or Selection-Event, no idea what you use) you have to grab the ID from its column (or from whereever)
    and execute the following 2 Queries
    2) SELECT Picture FROM Cards WHERE ID=?
    Set the Parameter for ID with that ID from the Column and grab the Picture
    Resulting RecordCount should be 1 --> Check for NON-NULL-Result of Picture

    3)
    Code:
    WITH 
        DT(Delimiter) AS (VALUES(';')),
        split(id,last,rest) AS (
            SELECT ID, '', Keywords FROM Cards 
            UNION ALL
            SELECT ID, 
            IIF(instr(rest,Delimiter)>0,substr(rest,1,instr(rest,Delimiter)-1),substr(rest,1)),
            IIF(instr(rest,Delimiter)>0,substr(rest,instr(rest,Delimiter)+1) ,'')
            FROM split INNER JOIN DT ON 1=1 WHERE rest<>'')
    
    SELECT ID, last As KeyWord FROM split WHERE last<>'' AND ID=?  --HERE THE PARAMETER!!
    ORDER BY lower(KeyWord)
    Set the Parameter for ID with the ID you grabbed from the Column
    Use that result to populate your Label (or whatever control you use) for your bulletpoints
    RecordCount can be anything
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  11. #11

    Thread Starter
    Addicted Member
    Join Date
    Nov 2022
    Location
    Manitoba, Canada
    Posts
    152

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Thank you but no, I don't plan on going back and using a delimiter now. I can see that you were correct from the start and that my table was structured incorrectly. I feel its important to do this properly if I'm going to learn anything.

    Going by your direction here:
    Quote Originally Posted by Zvoni View Post
    1) SELECT ID, Name FROM Cards ORDER BY Name
    Take the result from that and fill up that Grid on your left side
    I am able to do this successfully and hopefully correctly using my code below. With that said, I have added the "Picture" field to the query because I am binding that data to the picture box. I hope this isn't a mistake to do so? I have also changed the order. I have set the ORDER by ID instead of by Name since in this case the card's ID is how I want the cards displayed in the DGV. I have done all of this by implementing the following code:

    Code:
    Imports System.Data.SQLite
    
    Public Class frmMain
    
        Private ReadOnly dbCon As New SQLiteConnection("Data Source=" & Application.StartupPath & "\CardsSample.db;" & "Version=3;New=False;Compressed=True;")
    
        Dim Adapter1 As String = ("SELECT ID, Name, Picture FROM Cards ORDER BY ID ASC")
    
        Private WithEvents adCards As New SQLiteDataAdapter(Adapter1, dbCon)
    
        Private dtCards As New DataTable                                                    
        Private bsCards As New BindingSource                                                
    
    
    
        Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            adCards.Fill(dtCards)
    
            setupBindings()                                                                
            setupDGV()                                                                     
    
        End Sub
    
    
    
        Private Sub setupBindings()
    
            bsCards.DataSource = dtCards
    
            Me.lblCardName.DataBindings.Add("Text", bsCards, "Name")                       
            Me.PictureBox.DataBindings.Add("Image", bsCards, "Picture", True)              
    
        End Sub
    
    
    
        Private Sub setupDGV()
    
            With Me.DGV
                .DataSource = bsCards                                                       
                .DefaultCellStyle.Font = New Font("Tahoma", 9.75, FontStyle.Regular)       
                .DefaultCellStyle.SelectionBackColor = Color.Pink                           
                .DefaultCellStyle.SelectionForeColor = Color.Red                           
                .ReadOnly = True                                                            
                .AllowUserToResizeColumns = False                                          
                .AllowUserToResizeRows = False                                             
                .SelectionMode = DataGridViewSelectionMode.FullRowSelect                   
                .Columns("ID").Visible = True                                               
                .Columns("Name").Visible = True                                             
                .Columns("Picture").Visible = False                                         
                .AllowUserToAddRows = False                                                
                .RowHeadersVisible = False                                                 
                .ColumnHeadersVisible = True                                               
                .Columns(0).Width = 28                                                      
                .Columns(1).Width = 147                                                    
            End With
    
        End Sub
    
    
    End Class
    Regarding your second instruction:
    Quote Originally Posted by Zvoni View Post
    2) SELECT Picture FROM Cards WHERE ID=?
    Set the Parameter for ID with that ID from the Column and grab the Picture
    Resulting RecordCount should be 1 --> Check for NON-NULL-Result of Picture
    I am unsure why I need to query the Cards table for the picture data that aligns with the chosen ID in the highlighted DGV row? Each record in the Cards table is unique, meaning that with each ID, a unique card name and picture go along with it. There will never be a record in the Cards table that shares an ID, name and/or picture with any other record throughout the table. Therefore, can I not simply query the Cards table once like I have done and pull the picture data out at that time and then simply bind it to the Picture box? If there is a reason that I should not do this, I don't know what it is and would like some clarification if possible please. I'm not trying to be difficult, I'm genuinely curious if what I am doing is incorrect? Again, my code to achieve what I just mentioned is as follows:

    Code:
    Dim Adapter1 As String = ("SELECT ID, Name, Picture FROM Cards ORDER BY ID ASC")
    
        Private Sub setupBindings()
            bsCards.DataSource = dtCards
            Me.lblCardName.DataBindings.Add("Text", bsCards, "Name")                        
            Me.PictureBox.DataBindings.Add("Image", bsCards, "Picture", True)               
        End Sub
    Looking at your third instruction, I believe that I have a start in the right direction but please, correct me if I'm way out in left field. You said:
    Quote Originally Posted by Zvoni View Post
    3) SELECT Word FROM Keywords WHERE CardsID=?
    Set the Parameter for CardsID with the ID you grabbed from the Column
    Use that result to populate your Label (or whatever control you use) for your bulletpoints
    RecordCount can be anything
    As a means to grab the "ID" value from the highlighted DGV row, I have implemented the following code and it returns favorable results (using a message box to return the value as a visual aid):
    Code:
        Private Sub DGV_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DGV.CellContentClick
    
            Dim X As String                                                                
            X = DGV.SelectedRows.Item(0).Cells(0).Value                                     
    
            MessageBox.Show(X)
        End Sub
    At this point, I am struggling to move forward and out of time for today. It is my understanding that I will need to structure another query as you have noted (SELECT Word FROM Keywords WHERE CardsID=?) and I have captured the ID from the DGV selection but then I get lost. Also, I think its important that I wrap my head around my first set of questions that revolve around your second instruction above. Can I pull the Picture data from the original query right from the start or does it need to be a second query and why?

    I am out of time this morning and have to head to my regular job. I will revisit this after work and see what I can come up with. Lastly, I have opted to scrap the idea of populating a label with bullet points and have since chosen to do as you recommended. I have implemented a list box as the object that will hold the Words from KeyWord table.

    This is currently how the form looks with the listbox (framed for identification) in place of the old label.
    Name:  Screenshot_004.jpg
Views: 64
Size:  26.9 KB

  12. #12

    Thread Starter
    Addicted Member
    Join Date
    Nov 2022
    Location
    Manitoba, Canada
    Posts
    152

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Well....So far I have come up with this:

    Code:
        Private Sub DGV_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DGV.CellClick
    
            Dim X As String
            X = DGV.SelectedRows.Item(0).Cells(0).Value
    
            Dim Adapter2 As String = ("SELECT Word FROM KeyWords WHERE CardID=" & X)
    
            Dim adKeyWord As New SQLiteDataAdapter(Adapter2, dbCon)
    
            Dim dtKeyWord As New DataTable
            Dim dsKeyWord As New DataSet
    
            adKeyWord.FillSchema(dsKeyWord, SchemaType.Source, "KeyWords")
            adKeyWord.Fill(dsKeyWord, "Word")
            dtKeyWord = dsKeyWord.Tables("Word")
    
            Me.ListBoxKeywords.ClearSelected()
            Me.ListBoxKeywords.DataSource = dtKeyWord
            Me.ListBoxKeywords.DisplayMember = "Word"
    
        End Sub
    It seems to populate the listbox as I had hoped. I'm unsure whether this could be cleaned up or not? I used some example code I found online and adapted it to work with my parameters. I think....

    Is this the correct way of, or at the very least, one of the correct ways of doing what I want to do? Or have I made a mess of it?

    Shown below is the listbox displaying the data from the Words field from the KeyWords table in relation to the row selected in the DGV:
    Name:  Screenshot_005.jpg
Views: 42
Size:  34.4 KB
    Last edited by The_Hobbyist; Oct 2nd, 2024 at 02:22 AM. Reason: Grammar

  13. #13
    PowerPoster
    Join Date
    Sep 2005
    Location
    Modesto, Ca.
    Posts
    5,261

    Re: How can I use a delimiter to filter data from field then display as bullet points

    I believe I helped you setup a gemstone app. I might be wrong but if so,

    Then why not use a dataset and setup a relation between the two tables like we did in that app. Then keywords would be automatically displayed everytime you move from card to card in the dgv.

    If not that then I'd use your bindingsource PositionChanged event and not dgv CellClick event.

  14. #14

    Thread Starter
    Addicted Member
    Join Date
    Nov 2022
    Location
    Manitoba, Canada
    Posts
    152

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Quote Originally Posted by wes4dbt View Post
    I believe I helped you setup a gemstone app. I might be wrong but if so,

    Then why not use a dataset and setup a relation between the two tables like we did in that app. Then keywords would be automatically displayed everytime you move from card to card in the dgv.

    If not that then I'd use your bindingsource PositionChanged event and not dgv CellClick event.
    You did help me with that app! Unfortunately I am unable to find all of that source code in its entirety. I have found snippets of it that were stored on a flash drive but the entire project was lost to a bad hard drive some time ago.

  15. #15
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,736

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Looks good in post 12.

    regarding the picture, and why I don’t select it in the first query:
    you actually only need the picture AFTER you select an entry in your grid.
    there is no reason to hold a bunch of pictures in memory when you don’t need them.

    and in any case: you always only display one picture at any given time

    Yes, you said something about databinding, but i will not go down that rabbit hole.

    rule of thumb dealing with databases: you only select what you really need at any given time
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  16. #16
    PowerPoster
    Join Date
    Sep 2005
    Location
    Modesto, Ca.
    Posts
    5,261

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Quote Originally Posted by The_Hobbyist View Post
    You did help me with that app! Unfortunately I am unable to find all of that source code in its entirety. I have found snippets of it that were stored on a flash drive but the entire project was lost to a bad hard drive some time ago.
    This is a an example of how the relation and bindings would be setup,

    Code:
    Public Class Form1
        Private data As New DataSet
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
            SetUpDataSet()
            LoadTables()
    
            Me.BindingSource1.DataSource = data
            Me.BindingSource1.DataMember = "Cards"
            Me.DataGridView1.DataSource = BindingSource1
    
            Dim bs As New BindingSource
            bs.DataMember = "CardWords"
            bs.DataSource = Me.BindingSource1
            Me.ListBox1.DataSource = bs
            Me.ListBox1.DisplayMember = "Word"
    
        End Sub
    
        Private Sub SetUpDataSet()
            Dim CardsDataTable As New DataTable
            Dim WordsDataTable As New DataTable
            CardsDataTable.TableName = "Cards"
            CardsDataTable.Columns.Add("ID", GetType(Integer))
            CardsDataTable.Columns.Add("Name", GetType(String))
    
            WordsDataTable.TableName = "Words"
            WordsDataTable.Columns.Add("ID", GetType(Integer))
            WordsDataTable.Columns.Add("CardID", GetType(Integer))
            WordsDataTable.Columns.Add("Word", GetType(String))
    
            data.Tables.Add(CardsDataTable)
            data.Tables.Add(WordsDataTable)
    
            data.Relations.Add("CardWords", data.Tables("Cards").Columns("ID"), data.Tables("Words").Columns("CardID"), False)
    
        End Sub
    
        Private Sub LoadTables()
            data.Tables("Cards").Rows.Add(1, "Card1")
            data.Tables("Cards").Rows.Add(2, "Card2")
            data.Tables("Cards").Rows.Add(3, "Card3")
    
            data.Tables("Words").Rows.Add(1, 1, "Word1of1")
            data.Tables("Words").Rows.Add(2, 2, "Word1of2")
            data.Tables("Words").Rows.Add(3, 1, "Word2of1")
            data.Tables("Words").Rows.Add(4, 2, "Word2of2")
    
    
        End Sub
    End Class
    Of course you would get your data from your database.

    I just dropped a datagridview, listbox and bindingsource on the form from the toolbox.

  17. #17

    Thread Starter
    Addicted Member
    Join Date
    Nov 2022
    Location
    Manitoba, Canada
    Posts
    152

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Quote Originally Posted by Zvoni View Post
    .
    regarding the picture, and why I don’t select it in the first query:
    you actually only need the picture AFTER you select an entry in your grid.
    there is no reason to hold a bunch of pictures in memory when you don’t need them.
    This makes excellent sense to me. I think I'll go back and alter it so I do as you suggest and only call the picture out when needed. Smart!

    Thank you for the help! It has been greatly appreciated.

  18. #18

    Thread Starter
    Addicted Member
    Join Date
    Nov 2022
    Location
    Manitoba, Canada
    Posts
    152

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Quote Originally Posted by wes4dbt View Post
    This is a an example of how the relation and bindings would be setup,

    Code:
    Public Class Form1
        Private data As New DataSet
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
            SetUpDataSet()
            LoadTables()
    
            Me.BindingSource1.DataSource = data
            Me.BindingSource1.DataMember = "Cards"
            Me.DataGridView1.DataSource = BindingSource1
    
            Dim bs As New BindingSource
            bs.DataMember = "CardWords"
            bs.DataSource = Me.BindingSource1
            Me.ListBox1.DataSource = bs
            Me.ListBox1.DisplayMember = "Word"
    
        End Sub
    
        Private Sub SetUpDataSet()
            Dim CardsDataTable As New DataTable
            Dim WordsDataTable As New DataTable
            CardsDataTable.TableName = "Cards"
            CardsDataTable.Columns.Add("ID", GetType(Integer))
            CardsDataTable.Columns.Add("Name", GetType(String))
    
            WordsDataTable.TableName = "Words"
            WordsDataTable.Columns.Add("ID", GetType(Integer))
            WordsDataTable.Columns.Add("CardID", GetType(Integer))
            WordsDataTable.Columns.Add("Word", GetType(String))
    
            data.Tables.Add(CardsDataTable)
            data.Tables.Add(WordsDataTable)
    
            data.Relations.Add("CardWords", data.Tables("Cards").Columns("ID"), data.Tables("Words").Columns("CardID"), False)
    
        End Sub
    
        Private Sub LoadTables()
            data.Tables("Cards").Rows.Add(1, "Card1")
            data.Tables("Cards").Rows.Add(2, "Card2")
            data.Tables("Cards").Rows.Add(3, "Card3")
    
            data.Tables("Words").Rows.Add(1, 1, "Word1of1")
            data.Tables("Words").Rows.Add(2, 2, "Word1of2")
            data.Tables("Words").Rows.Add(3, 1, "Word2of1")
            data.Tables("Words").Rows.Add(4, 2, "Word2of2")
    
    
        End Sub
    End Class
    Of course you would get your data from your database.

    I just dropped a datagridview, listbox and bindingsource on the form from the toolbox.
    I'm going to dive into this after work tonight. Thank you! I will report back with my results and/or questions. As always, I appreciate the help. Thank you.

  19. #19
    PowerPoster
    Join Date
    Sep 2005
    Location
    Modesto, Ca.
    Posts
    5,261

    Re: How can I use a delimiter to filter data from field then display as bullet points

    Quote Originally Posted by The_Hobbyist View Post
    I'm going to dive into this after work tonight. Thank you! I will report back with my results and/or questions. As always, I appreciate the help. Thank you.
    If you are retrieving the photo and/or KeyWords as needed then use the Bindingsource PositionChanged event not the dgv CellClick event. A dgv cell can be clicked for various reasons, it doesn't mean that the dgv has moved to a different row. No need to be retrieving data from the database unless the dgv position has changed.

    Code:
        Private Sub BindingSource1_PositionChanged(sender As Object, e As EventArgs) Handles BindingSource1.PositionChanged
            If Me.DataGridView1.CurrentRow IsNot Nothing Then
                Dim row As DataRow = DirectCast(Me.BindingSource1.Current, DataRowView).Row
                ' Retrieve the photo/keywords here, using row("ID").ToString to locate the correct record
                ' 
                'you will also need to load the photo in the FormLoad event
            End If
        End Sub
    Last edited by wes4dbt; Oct 2nd, 2024 at 04:52 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width