Bulk insert to Power Apps collection

In this blog, we will show you the technique used to collect tables for your app by using the bulk insert. We will show you how to make the same table structure in Power Apps as Excel tables. We will use Excel to show you how to copy-paste tabular data from it and collect it inside the Power Apps collection (the technique is not only limited to Excel). This is used mainly when you can predict the order of the columns in tables you wish to collect. If you don’t know the exact order in which you will collect data, then this solution will not work for you. We will show you in the following blog post how to do this technique dynamically to solve the ordering problem.

We will go through this technique step by step, and that includes making some mistakes and resolving them. If you are not interested in going through this step by step, you can skip to the end of the blog and see the full code for bulk insert.


Problem with Pasting from Excel

First, let’s look at the example involving a situation where you want your users to be able to paste Excel tables in the Text Input field and collect them to the Power Apps collection. We will consider the situation where we want users to collect data containing information about the quantity of the products sold. The table will contain columns CustomerID (containing customer that bought the product), Product (product name), Quantity (quantity sold) and Date (today’s date). Our interface is very simple and looks like this:

We have text input named TextInput1, button named CollectButton which is used to collect data, and the data table with the BulkCollection as the source to see the collection and find out if our code is working (in your real solutions you might have a gallery there instead). In short, in our text input, we will paste tabular data from Excel, collect it with CollectButton, and see if our data table looks exactly like in the Excel table.

For the sake of simplicity, we’ll use the Excel table containing 5 rows:


Altering OnSelect property of the CollectButton

To achieve our goal, in the OnSelect property of the CollectButton, we will write the code using the combination of the ForAll() function with the Split() and Collect() functions. You can find the explanation below the code.

Clear(BulkCollection);
ForAll(
    Split(
        TextInput1.Text,
        Char(10)
    ),
    Collect(
        BulkCollection,
        {
            CustomerID: First(
                Split(
                    Result,
                    Char(9)
                )
            ).Result,
            Product: Last(
                FirstN(
                    Split(
                        Result,
                        Char(9)
                    ),
                    2
                )
            ).Result,
            Quantity: Last(
                FirstN(
                    Split(
                        Result,
                        Char(9)
                    ),
                    3
                )
            ).Result,
            Date: Last(
                FirstN(
                    Split(
                        Result,
                        Char(9)
                    ),
                    4
                )
            ).Result
        }
    )
)

Although the function is relatively long, the code for each column is almost identical. After clearing the InsertedCollection, we use the ForAll loop to iterate through each row of the TextInput1 (same as going through each row of the Excel table). For each row, we will collect data to our InsertedCollection. For example, we have row 1 from our Excel table containing customer 1, who bought 20 pairs of shoes on the date 3/8/2020. With the Split() function, we take the first row containing 4 different words and split it by Char(9) separator (which is a tab inside Excel). For example, for the first row, we get a table with 4 rows:

Now, to get the first row of this table (for CustomerID column), we use First(***).Result. For the second column (Product), we use Last(FirstN(***),2).Result, because in that way, we will first filter the table from the Split function to contain only the first two rows, and after that, take the last row (i.e., the second row of the table). The rest of the code is the same for every other column, with the only difference in the argument of the LastN() function (depending on which row from the Split table we want to get).
This will happen for each row of the table, so our collection should contain a complete Excel table. When we test this code, the result is not good:

Since we copied the headers of the table (they are now the first row of the table), we got the headers and the last row with blank value in our collection. To prevent this, at the end of the OnSelect property of the CollectButton, add the RemoveIf() function to remove unnecessary rows.

RemoveIf(
    BulkCollection,
    CustomerID = "CustomerID" Or CustomerID = ""
)

This will remove the first row containing a header, and the last one containing the blank value.
To make it case insensitive, add Lower() function in front of the CustomerID column.

RemoveIf(
    BulkCollection,
    Lower(CustomerID) = "customerid" Or CustomerID = ""
)

Testing the Solution

If we test our app now, we get the result without unwanted rows.

The last problem here is that our Quantity and Date columns data type is text. In order to resolve this problem, we will use the Value and DateValue functions within our code to convert strings into the required data type.

The final code for CollectButton’s OnSelect property:

Clear(BulkCollection);
ForAll(
    Split(
        TextInput1.Text,
        Char(10)
    ),
    Collect(
        BulkCollection,
        {
            CustomerID: First(
                Split(
                    Result,
                    Char(9)
                )
            ).Result,
            Product: Last(
                FirstN(
                    Split(
                        Result,
                        Char(9)
                    ),
                    2
                )
            ).Result,
            Quantity: Value(
                Last(
                    FirstN(
                        Split(
                            Result,
                            Char(9)
                        ),
                        3
                    )
                ).Result
            ),
            Date: DateValue(
                Last(
                    FirstN(
                        Split(
                            Result,
                            Char(9)
                        ),
                        4
                    )
                ).Result
            )
        }
    )
);
RemoveIf(
    BulkCollection,
    Lower(CustomerID) = "customerid" Or CustomerID = ""
)

Our collection now has all the necessary data, as well as the correct data types.

In the following blog post, we will describe how to avoid getting duplicate values when using this technique. It is important to notice that by using this technique, we are referencing column orders in our code (in the FirstN count argument). This means that if the order of the columns from the Excel table is not exactly like in our code, this technique will fail and show incorrect data. As mentioned, this will also be the topic of our future blog, in which we will show how to avoid the column ordering problem.

I hope it helps you in developing your apps. If you have any questions or comments, please leave them below!

Table of Content

Table of Content

LEARN POWER QUERY

Improve your PowerQuery skills with
Exceed Academy

COMMENTS

Subscribe
Notify of
guest
3 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

GET LATEST BI NEWS TO YOUR INBOX

Receive the latest updates on all business analyst news across all platforms.

By subscribing you are agreeing to our Privacy Policy.

Related blog posts

DAX HANDBOOK
7. VARIABLES

Variables are used in almost every measure you will create. The reason we introduce them last is that they use all other parts of DAX code to produce faster, more powerful and maintainable code. Variables are like containers of a part of the DAX code which can be used throughout...

Read more

DAX HANDBOOK
6.8 ALLSELECTED

Explanation ALLSELECTED is one of the most complex functions in DAX. When used improperly it can lead to unexpected results. As a rule of thumb, you should not use it in iterative functions. It is preferable to use it only as a CALCULATE filter remover, not as a table function....

Read more

DAX HANDBOOK
6.7 Lineage

What is Lineage? Lineage is a part of DAX mechanics that enables us to use tables as filter arguments for the CALCULATE function. It’s also used in row2filter context transition and other aspects of the data model that involve filter propagation throughout the model. We can state that lineage is...

Read more

DAX HANDBOOK
6.6 Crossfilter

Crossfilter is a feature of DAX when it filters the underlying dataset even though there aren’t any visual filters present. Introduction In this example, we will explain a very important feature of CALCULATE filter arguments. We will also explain why you should always prefer the combination of ALL/REMOVEFILTER + VALUES...

Read more
3
0
Would love your thoughts, please comment.x
()
x
Scroll to Top