Call dialogue box for OData feed authentication - excel

I have an Excel workbook that pulls fact tables from Dataverse for Teams via Power Query. This workbook is shared across our organization. The users are (for the most part) technically naive. So when a query fails to refresh due to lack of authentication, I need the authentication dialogue box to automatically pop up.
I'd like to write a Workbook_Open sub to check if the user is signed in to a particular OData connection. If they are not, I'd like to call the dialogue (pictured above) so that they can sign in before it causes them any issues.
My problem is, I can't find any documentation showing which object(s) and methods to use. Any ideas?

You might call this Sub as the application will use the users default browser to establish a new window:
Sub sbVBA_To_Open_Website_URL_FollowHypderlink()
Dim strURL As String
strURL = "https.//org16c3abbe.crm.dynamics.com/"
ThisWorkbook.FollowHyperlink (strURL)
End Sub

Related

Sync or link Excel Spreadsheet with Outlook Calendar

Good morning,
I would like to sync my Excel Spreadsheet with Outlook calendar.
This spreadsheet is to be updated every 5-10 mins. Is it possible to set some periodic updates or shall I do everything manually?
I found a lot examples in the web, showing how to export Excel data to Outlook, but there are only single operations, that must be repeated.
One reasonable option is provided here:
https://classroom.synonym.com/sync-yahoo-calendar-android-device-8556.html
but is pretty much other way round what I am looking for, because it's embedding calendar to the Excel.
I would like to link Excel Sporeadsheet with Outlook calendar.
Is there a some way to do this i.e via VBA, PHP, SQL etc?
Usually programming such an action can be done in two ways: Polling or event driven.
Polling means using a timer to do your work repeatingly every period of time. Search for 'VBA' and 'timer'.
Event driven means you will take a subscription on an event. The other side will raise an event when something has changed. Like a subscription on a newspaper: the newspaperboy delivers a newspaper when something happened in the world. When you hear or see the newspaperboy, you walk to the mailbox and empty it.
Usually event driven is the most beautiful solution, because it doesn't use a lot of CPU (with the newspaper example, you can sit back and relax until a newspaper is delivered). But when you are polling, you will have to check the mailbox (calendar) every time.
Here is a Items.ItemChange event about when an item has changed. I hope it fits your needs. If you want to understand better how it works, search for "event handling".
If the link is broken, here is the example from that page:
Public WithEvents myOlItems As Outlook.Items
Public Sub Initialize_handler()
Set myOlItems = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderCalendar).Items
End Sub
Private Sub myOlItems_ItemChange(ByVal Item As Object)
Dim prompt As String
If VBA.Format(Item.Start, "h") >= "17" And Item.Sensitivity <> olPrivate Then
prompt = "Appointment occurs after hours. Mark it private?"
If MsgBox(prompt, vbYesNo + vbQuestion) = vbYes Then
Item.Sensitivity = olPrivate
Item.Display
End If
End If
End Sub

How to implement user-level security in Access 2007

So after some digging I realize that there is no built in user level security option for Access 2007. What I need to do is restrict records that users can edit based on who is logged in (they can see all the data but only edit their own). I was thinking that I could make a log in form and assign passwords and go from there, but I was wondering if there was a better method to do this.
For user privileges for read-only, read-write on forms in the database, we implemented following tables, logic.
I created a privilege table along with log-in table. Each screen in the database will have Read-only or Read-write privilege to each user. I inserted all the screen names into privilege table. Another table UserPrivilege will have users and their privileges. Assigning privilege to an user will be done only by Admin user.
A function at start of each form check swhether a specified user is allowed to view or edit form. If he/she is given read-only, we will lock all controls looping thr' controls on the form. Else, nothing to do. OR keep all the controls read-only at design them and unlock them thr' code for write privilege.
The database window is kept hidden when a version to end user is delivered. This prevents usual , simple view to tables in the database, opening forms , reports object in database window. After making mde/accde few more tweaks can be done so that user is not easily able to view tables directly. by-passing startup, special keys etc.
I have been facing this problem too. My solution (which hasn't been broken yet) is to do exactly that. Make a user's table with passwords and a log in form which reads the table for User name, password and user type. I have used two ways to proceed from there: Case statement to open specific navigation forms for that user's functions or a global variable (in a module (enumeration helps)) and an getter function that is checked within each form's open events and changes properties like AllowEdits, and AllowAdditions and even cancel the form opening if it's administrative stuff.
The most important part of this set up is making sure the users are using Access Runtime. If they use the Access version you are developing in they can snoop a little bit and get around this.
Make sure you hide the user's table.
Access runtime can be forced by making a shortcut to the DB and adding /runtime to the end of the shortcut path (with a space).
It's not perfect, but it works for my purposes and It might work for your's.
I did dot this in 2010, but 2007 should be pretty much the same.
Assigning username/passwords in Access (especially with an access back end) has a number of critical issues that are worth pointing out. Firstly, if you don't encrypt your DB, then any of your users who are savvy enough to go looking for it will be able to find it, and therefore get full access to it. If you encrypt the DB, if anyone can get access to your source code you're toast, since they will be able to see the DB user/passwords stored in the code. This issue persists if you use other SQL db's, but at least in those cases you can restrict the user supplied to the Access .accdb file to have certain permissions.
For my case, I have 3 levels of security. Firstly, I heavily restrict what I send out to make it very difficult to access the source code, which you kind of have to do no matter what. Secondly, I distribute different levels of access with different DB passwords (I'm using a MySQL back-end, you could do the same with a SQLServer back-end, but with Jet you're out of luck), so even if users could see the DB user and password, they are limited in what they can do. Thirdly, since I deploy on a corporate network, I take advantage of windows groups, and use those to filter out what is visible to different users. That way, users can only use the forms if they are authenticated onto our network. If the file discovers it's not on the network, it deletes itself and terminates.
Function IsMember(strDomain As String, strGroup _
As String, strMember As String) As Boolean
Dim grp As Object
Dim strpath As String
strpath = "WinNT://" & strDomain & "/"
Set grp = GetObject(strpath & strGroup & ",group")
IsMember = grp.IsMember(strpath & strMember)
End Function
Function GetCurrentUser() As String
GetCurrentUser = VBA.Environ$("USERNAME")
End Function
Function GetCurrentDomain() As String
GetCurrentDomain = VBA.Environ$("USERDOMAIN")
End Function

Lotus notes - error accessing shared private on first use view from LotusScript

Good morning,
I have develop a note application which is used to make a booking. This application is used by multiple user at the same time.
I am quiet new to this development and now I would like to develop a functionality so that user can print a export data to excel.
I have created a view (Shared) where its Selection Formula is base on critical each user specify in a search form. I have problem when a user is being printing and yet finished, the other users is also clicking printing same time, the result of export data on the sides are the same to the one who created first.
I was thought may be using the kind of (Shared, Private on first Use View) but it generated an error [Notes error: Index is not to be generated on server ("view name") ] at the points where I called
view.Clear
view.SelectionFormula = formula
uiw.ViewRebuild
I have no idea how to solve this problem. Could you please advice how this problem could be solved?
Thanks your in advance for your great help.
Best regards,
Veasna
There are different ways to do this. One possibility is to use a "shared, private on first use" (spofu) view: then every user gets his own copy of the view, and they don't impact each other. But I think it is not a good idea to do it like that, as every user needs designer rights to change the selection formula of the view. This is something you do not want.
A better way would be to use a spofu folder for each user and put the documents in it like this:
Dim ses as New NotesSession
Dim db as NotesDatabase
Dim dc as NotesDocumentCollection
Dim folder As NotesView
Dim formula as String
Set db = ses.currentDatabase
Set folder = db.GetView("NameOfTheSpofuFolder" )
'Make it empty
Call folder.AllEntries.RemoveFromFolder("NameOfTheSpofuFolder")
'Search documents based on the formula
Formula = "Field1 = 2 & Field2 = 5"
Set dc = db.Search( formula, Nothing, 0)
Call dc.PutInFolder("NameOfTheSpofuFolder")
Spofu folders need a little "care" but usually they work quite nicely.
This code is not tested and just written down without syntax check etc. It might contain typos, but should give you an idea how to start.
You could create a Lotusscript agent to export the data the users specify.
Get the search criteria from the form, then use db.Search or (preferably) db.FTSearch to get the documents to export.
Now you can export the data of those documents to Excel, using one of the techniques described here:
http://blog.texasswede.com/export-from-notes-to-excel-3-different-ways/
If you want to export as CSV, you can use this code as a start: http://blog.texasswede.com/export-notes-view-to-excel-with-multi-value-fields/
According to this thread on the Notes 6/7 forum, there may be a workaround for this problem. You haven't shown enough code to know for sure. If you are using getView() to access the Shared - Private On First Use (SPOFU) view, that doesn't work. The workaround is to loop through the db.Views() array, checking both the Name and Readers properties in order to make sure that you get a handle on the private instance of the view instead of the shared instance.

PivotTable with dynamic Query to External Datasource

My question is less specifically looking for ideas to a solution, and more for a sanity check of my own solution since it's been a while (at least two major revisions) since I've worked with ADODBs in Excel VBA.
So the situation is this. I'm creating an Excel report for a user who wants to access large chunks of a database view that is much too big to fit in memory. The user needs to be able to access ALL of the view, so hardcoded filters are out of the question. Unless I'm missing a more elegant solution, what they need is to be able to dynamically control the filters on the connection in the form of a generated SQL statement, which feeds into the pivotcache and then tells the pivottable to refresh.
I created a "refresh" button which brings up a Form that has all the filters the user commonly needs. The user enters the filter values, I parse and validate them, form a proper SQL statement from the values. Then I run into a problem when I do this:
'this has to be dynamic becuase I'm distributing to multiple users, using different testing/production databases on different workstations.
mypivottable.PivotCache.Connection = "ODBC;" & driver & myserver & myuser & trusted & app & workstationid & databse
'this also has to be dynamic becuase of the sql filters
mypivottable.PivotCache.CommandText = sql
So I push the button and it works! after setting these properties the pivottable automatically refreshes because it knows there's new data behind the cache, and fetches the query results under the new criteria.
The problem is that when I look in the external datasource listing, every time I change these properties it creates a new connection and doesn't clean up after itself. After 100 uses, there are 100 connections laying around, 99 of them unused. If I delete ALL the connections, then it irreversibly breaks the pivottable.
Is there a better way to do this? Is there a programmatic way to clean up only unused connections?
You don't have to reset the connection if all you need to do is update the SQL statement. I actually had a similar issue to this and this is how I resolved it:
Sub test()
' add logic...
' then change sql code
With ThisWorkbook.Connections("your connection name").OLEDBConnection
.CommandText = Array("select * from mytable where id = 1") ' adjust accordingly
.Refresh
End With
End Sub
All you really need to do is grab the current connection then update the CommandText property. By the way, I'm not sure why I needed to use Array() but I had issues without it.
I actually wrote a blog post about using SQL to create a pivot table (link here). Maybe I should make another one about creating dynamic content :)

Using VBA to read the metadata or file properties of files in a SharePoint doc library

I have a few hundred Word templates (DOTX) on a SharePoint site. Many teams of users work with these templates.
When a user needs to customize this documentation, they click a special link on SharePoint to generate a new document (DOCX) from the template they choose. This new document file always needs to be "linked" back to its template file on SharePoint. If the document loses that link, it won’t work correctly and is considered “broken”.
When documents break, I need to re-establish the link back to the right template on SharePoint. It makes sense to do this programmatically so I can distribute the solution to my team.
I want to give each template file a unique Template ID (a three-digit number), stored in metadata or a custom file property. When new documents are generated from the templates, the Template ID automatically carries over into the document, so that’s set. Now I just need to use VBA to scan the template files in the SharePoint document library for the matching Template ID. When that’s found, I can re-establish the link and all is well.
I’m basically looking for this:
Sub DocFixer()
Dim objTemplate as Template
Dim objBrokenDoc as Document
Set objBrokenDoc = ActiveDocument
For each objTemplate in "\\SharePoint\Template Library\".Templates
If objTemplate.Properties("Template ID").Value = objBrokenDoc.Properties("Template ID").Value Then
objBrokenDoc.AttachedTemplate = objTemplate.Path
Exit For
End If
Next
End Sub
…but I’m having trouble using VBA to read SharePoint doc library contents without actually opening the contents, as that takes far too long with so many templates, plus its very disruptive for the user.
Any ideas? Could you point me in the right direction?
Edit: Here's my solution:
Sub Macro()
Dim FSO As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Dim objFile As Object
Dim objDSO As Object
For Each objFile In FSO.GetFolder("\\SharePoint\doc lib\").Files
Set objDSO = CreateObject("DSOFile.OleDocumentProperties")
objDSO.Open objFile.Path
If objDSO.CustomProperties.Item("Template_ID") = ActiveDocument.CustomDocumentProperties("Template_ID").Value Then
ActiveDocument.AttachedTemplate = objFile.Path
End
End If
Next
MsgBox ("No matching template found. Please attach the proper template manually."), vbCritical
End Sub
Apparently this taps into DSOFile.dll (http://technet.microsoft.com/en-us/library/ee692828.aspx), but I didn't have to add the reference? Still confused on that part.
Also, this might not work over https:// (SSL). Worked for me though, so I thought I'd share.
I would start by calling the SharePoint web services from VBA.
Once there you can make a call to GetListItems that will pull back the document with the correct TemplateID attribute directly.

Resources