Wednesday, May 24, 2017

Random gotcha when filtering values greater than 0 in PowerBI

This might be know to all PowerBI guru’s out there, but as I’m a newbie doing this and couldn’t find an article right away I figured I’d jot it down for future reference. And a big thank you to my colleague Marius (the CRM Viking), for letting me in on this secret.

I was trying to add a filter to a visualization, showing only values greater than 0.

image

for some unknown reason this did not work for some of my datasets. I could see a big fat zero in the data set, but the data still showed after I applied the filter. Changing to “is greater than or equal to 1” did the trick.

image

Could be something obvious wrong in my data transformation – but might be worth trying if you are trying to filter on values greater than zero/0.

Thursday, May 18, 2017

Three reasons why you should take control of Office 365 Groups creation

Office 365 Groups are here to stay and I’ve gotten to love them more and more, and for the past six months this is primarily what we at Puzzlepart are rolling out with our customers. If you’ve followed some of my work recently you know that I do a lot of work on provisioning solutions. Not as is a lot of code, but help organizations figuring out business needs and orchestrating them programmatically.

A provisioning solution is the code and logic which creates the pieces of for example an Office 365 Group. Instead of having Microsoft do everything, we add custom business logic on top of the default parts to solve other business needs.

In this post:

You can very well run with the out of the box ways to create new Office 365 Groups, but our customers often experience this to be lacking in many ways – as they want more metadata and governance around the groups themselves. Especially on the associated team site.

image

By creating an alternative self-service solution, for example based off a SharePoint list, you get more control. Below I’ll list my top three reasons why you might want to take control over the Office 365 Groups creation, and I’ll follow up with what has to be in place to make this work.

Tuesday, May 16, 2017

Using Azure Information Protection (AIP) Labels in SharePoint search

Azure information protection let’s you classify and add policies to documents regardless of where they are stored, but is tied to an Office 365 tenant. AIP operate directly on the Office files, and is currently available when using the desktop versions of Office (versions 2010/13/16)  on Windows (versions 7/8/10) – when you have installed the AIP client.

This means that even though you save copies or e-mail the files, AIP is still tied to the document.

Note: See the pricing plans page to see which SKU’s include AIP.

Resources about AIP

The Office Graph is dead, long live the Microsoft Graph!

Yesterday Microsoft announced two new Insights endpoint (in beta) to the Microsoft Graph in addition to the trending one which was already there. The new endpoints are:
  • Used - returns the most relevant documents that a user viewed or accessed
  • Shared - files shared with or by a specific user
All great news, but at the same time Microsoft announced discontinuation of the Office Graph GQL API’s – effectively killing the last remains of what was formerly known as the Office Graph. This means as of August 31st 2017, calls using GQL on the SharePoint search API will no longer work.

By June 1st you need to add the parameter EnableLegacySPOGraph=true to your GQL calls to extend the life until the final cut off date August 31st.

rip graphReaper and halo’s!

Monday, May 15, 2017

Saving a collection of images from PowerApps to SharePoint using Microsoft Flow

Yesterday I wrote about how you can save an image from PowerApps to a SharePoint library using Microsoft Flow – after reading about Paul Culmsee’s approach using Azure Functions. Paul challenged me to save a whole collection of images, and not only one image, so here goes!

This solution loops the images in Flow, but you could easily have looped them in PowerApps as well, saving one image at a time upon submit.

I’ll start with the Flow, and this time we’ll use one input only. And this is where it get’s a bit nasty. A Flow can only accept strings as input from PowerApps, not a collection of items. To overcome this, I’m concatenating the data into one string in the PowerApp, and then splitting the data in the Flow.

The data being passed in looks like this:

Monday, May 15, 2017LT.jpg|data:image/jpeg;base64,<data>#
Monday, May 15, 2017AB.jpg|data:image/jpeg;base64,<data>#


First is the filename with a readable date (borrowed code from Paul), next a pipe | to separate the filename from the base64 encoded image. And at the end a hash # to separate each image from each other.

In Microsoft flow create a new Flow named “Save Images”

Add a “PowerApps” step, followed by a “Compose” step.

image

In the input field for the “Compose” step pick “Ask in PowerApps”. Next change the formula to:

"@split(triggerBody()['Compose_Inputs'], '#')"

and rename the compose action to “Split images” for readability. This will split the incoming string on the character #, creating an array with one item per image.

Note: Remember to include the double quotes around the formula.

image

Below the “Split Images” action, add a “Filter array” action. This action is used to remove the empty element we get at the end when creating the data string in PowerApps. Use the Output from the previous action as the “From” field, click “Edit in advanced mode” and use the following formula to remove empty values. item() will yield one item in an array.

@not(equals(item(), ''))

Note: No quotes here :)

image

Below the Filter array action, add a for each item loop, so that we can process each image sent over.

image

Pick the Body output from the Filter array step as the input in the for each.

image

In the for each action, add two compose steps. Rename one to “Filename” and the other to “File content”.

For filename add the expression:
"@split(item(),'|')[0]"

For file content add the expression:
"@base64ToBinary(replace(split(item(),'|')[1],'data:image/jpeg;base64,',''))"
"@dataUriToBinary(split(item(),'|')[1])"

The effect is that for each item, split on the character |, and assign the left side as the filename, and base64 decode the right side of the split.
Note: Remember to include the double quotes around the formulas.
image

The last part is adding an action step to create a file in SharePoint. Pick a site and library, and assign the values from the previous compose steps.

image

Setting up the PowerApp

image

For the purpose of this demo I have four controls on in my app. A camera control, a button to send it all to flow, a clear button and a gallery to see the images taken, and which will be sent over to SharePoint.

To grab an image I have the following formula on the OnSelect property of the camera control:

Collect(PictureColl,Camera1.Photo)

This stores each image in a collection named PictureColl.

The gallery control’s “Items” property it bound to the PictureColl collection.

The “OnSelect” property of the submit button contains the following formula:

ForAll(PictureColl,Collect(SubmitData, { filename: Concatenate(Text( Now(), DateTimeFormat.LongDate ),Mid("0123456789ABCDEFGHIJKLMNOPQRTSTIUVWXYZ", 1 + RoundDown(Rand() * 36, 0), 1),Mid("0123456789ABCDEFGHIJKLMNOPQRTSTIUVWXYZ", 1 + RoundDown(Rand() * 36, 0), 1),".jpg"), filebody: Url }));

SaveImages.Run(Concat(SubmitData, filename & "|" & filebody & "#"))


The formula creates random filenames with dates and assigns the filename and image date to a collection named SubmitData (borrowed from Paul’s post). Then the file data is concatenated using a pipe | between the filename and the file contents, and concatenated using a hash # between each image. This is then passed into the SaveImages flow I have added to the PowerApp.

If you run the PowerApp (except in the Windows desktop version), tap the camera a couple of times to grab images, and then hit the submit data, you should end up with some images in your library.

image

See my previous post about on how to add a Flow to the PowerApp using PowerApps studio.

Sunday, May 14, 2017

An even more clever workaround for saving photos to SharePoint from PowerApps – using Microsoft Flow

At the time of writing there is a gap using PowerApps with SharePoint which won’t let you save a captured image from PowerApps directly to SharePoint. There are numerous posts out there about this, and Paul Culmsee wrote a post with a clever work around using Azure functions to get the image over to SharePoint.

Paul posted about this in Facebook, and cheeky me replied:
 
image

Note the (not really) at the end there, so I blame Paul entirely for making me write this post, which I think introduce an even more clever way of doing this – doable for any power user out there :D

I’ll skip all the fancy parts which Paul has to get nice random file names etc, so head over to his post for that piece of the pie.

A small note to Paul, and every one else – this will not work for the Windows desktop version of PowerApps – as it stores the captured image different compared to other devices. Instead of using the data uri notation with the full image base64 encoded, it only has a blob reference.

I’ve tested it with great success on:
  • Web
  • Windows Phone – Win10
  • iPad – iOS 10.3.1
So how do you do this? (I strongly urge you to read his post first, as it explains it all in very detail, where as I jump to the gist of things.)

First off, create a new PowerApp and add a camera control to the canvas. For the OnSelect command for the camera add the following command:

ClearCollect(PictureColl,Camera1.Photo)

When you click the image box it will grab the photo, and store it in a collection named PicureColl. As I’m using ClearCollect, the collection will always be cleared first, having one image only in the collection.

image

Next, I added a button which will send the image to SharePoint via Microsoft Flow. So let’s head over to Flow and see what the Flow looks like?

First add a collect from PowerApps actions. Then add a Create file in SharePoint action. For the file name and content, click “Ask in PowerApps”. This will generate two input variables, which we will use to pass in information from the PowerApp to the Flow.

image

Next, add a Compose step between the PowerApps action and the create file in SharePoint action. This is where we will strip away the base64 header, and convert the data to binary. You can type formulas directly into the SharePoint step as well, but I find it easier to manage this way.

The formula in the compose step is:

"@base64ToBinary(replace(triggerBody()['Createfile_FileContent'],'data:image/jpeg;base64,',''))"

"@dataUriToBinary(triggerBody()['Createfile_FileContent'])"

NOTE: It’s important to add the quotes "" before and after the expression, even though they don’t show on edit.

Next change the File Content box to retrieve the Output from the compose step instead of the collect from PowerApps as seen below.

image

And that’s it for the Flow, and head back to the PowerApp. Using PowerApps studio add a Flow to your app.

image

For the OnSelect command for the button add the following:

Saveimage.Run("test.jpg",First(PictureColl).Url)

Saveimage is the name of the Flow, which takes two parameters. The first being the filename, the second being the base64 encoded image from the Url parameter of the image. (All this is in Paul's great post.)

Fire up the app, click once on the image, and once on the button, and you should see a nice picture stored in your SharePoint library.

image

You can very well combine the OnSelect statements into either the image or button control if you want, but that’s all in how you want to have your UI. Having two controls made the demo simpler :)

Friday, May 12, 2017

How to remove the banner on modern pages using Office PnP PowerShell

image

While we’re waiting for full support for modern pages and how they work in Office PnP and the SharePoint Framework, here’s how you turn off the banner on article pages – basically setting them to the layout used by the Office 365 Group Team sites.

If you want to turn the banner back on, set the PageLayoutType to “Article”.

# Connect to the site
Connect-PnPOnline https://tenant.sharepoint.com/sites/portal

# List all pages, and find the id of the modern page
Get-PnPListItem -List SitePages

# Change layout from "Article" to "Home" to remove top banner
Set-PnPListItem -List SitePages –Identity <id> -Values @{"PageLayoutType"="Home"}

image

Monday, May 8, 2017

How to enable results from private groups on an Enterprise Search Center

image

Ever since private Office 365 Groups were launched we have been troubled with search in these sites. First it didn't work at all, but later Microsoft made it work in the site itself, in Delve and on the SharePoint home page. Seems they forgot about the Enterprise Search Center.

Note: This is not an issue with Public Office 365 Groups- and seems to work in First release tenants as well

I have previously written about how to get results from private Office 365 Groups using REST, but for the vast majority of people out there you probably want to enable this on your Enterprise Search Center as well. If you have an issue with this, here’s how to make this work.