Showing posts with label work projects. Show all posts
Showing posts with label work projects. Show all posts

30 April 2016

existence | renewal

/EXISTENCE
I'd like to preface this posting stating that although I did SharePoint posts in the past, I haven't touched it in 3 years. In some ways I miss it. In more ways I don't. But regardless of my feelings toward SharePoint, it has been too long since I posted anything here. And so like a phoenix from the ashes, I'm revitalizing this blog with new content.

In the coming posts I'm going to dive both into things I've been doing in and outside of work, though mostly inside work since that's where I've learned the most. Nearly 3 years ago I moved to Southern California and I've been doing IT Support and System Administration. We're the local area outsourced IT department for many clients, none of whom I'll mention both due to respect and an NDA. To give you an idea, our work ranges from helping a small local shop keep their Windows XP machines running their business to getting a new production printer setup for a 70+ person office part of an international group of companies. I've worked with Exchange servers, Windows Server 2000 - 2012 R2, Google Apps, Office 2007 - 2016, Adobe CC, Office 365, Okta, VMWare vSphere, Yosemite backup, Dell Compellent Storage systems, Dell Equalogic, SonicWALL firewalls, Apple Mac OS X 10.6 - 10.11, SMB sharing, QNAP, Lenovo, Barracuda, Cisco Aironet wireless, Dell network switches, and more things than I can remember.

My co-worker and I discuss things a lot. Many of the things we've learned are because we were poking about in settings trying to fix some esoteric issue. Sure we get hints from other postings online that talk about other settings or tweaks, but there doesn't seem to ever be nearly enough information. And in the end it's often some check box buried in the advanced settings. So I decided to start a new set of posts regarding these strange issues that are solved by changing one solitary setting. These posts will have "that damn check box..." in the title to indicate what kind of post it is.

The last thing I want to mention is that although I've learned a ton in the last 3 years, I'm rather worn out from this job. It's full of pressure to make things better for users and full of users that are mean. There are plenty of people I've met that are actually quite nice about it, but those mean ones tend to leave a mark. I hope writing about the issues I fix and my current life helps put me in a better head-space as well as enlighten others crazy enough to be in IT support. Additionally I'm quite tired of the busy-ness that is Los Angeles and Orange County. For my own health I believe I need some place a bit slower paced. This not only leads to that I'm looking for new employment, but I'm also looking to relocate. I haven't truly decided on where I want to go, but I've been thinking a lot of the life I left behind when I moved to SoCal in the first place.

It's hard to close my existential posts sometimes. I feel like I need to say something poignant, but I can never find the words. Sadly those words rarely coalesce. So...

Until next time:
Work smart. Play hard. Sleep well.

11 March 2013

codeless: temporary variables

/TECH
One of the problems I ran into in January was that the userName() function in InfoPath returns something different when used on a web form in a claims-based environment. This post will walk you through two things: creating "temporary variables" in InfoPath and sanitizing the userName() result.

Temporary variables are wonderful in programming and I missed them dearly when I started working with InfoPath. Typically I'd just make a field in some obscure part of the form and not publish it, but there was always a chance that someone with some know how could find that data. It became even more prudent when I started experimenting with a service that retrieved a list of the current user's SP security groups. So I finally searched for a solution. I don't remember who's blog I read first, but there are lots of results out there that all say the same thing: use an XML file.

It's a pretty simple and clever solution. Since data connections can either be "read" OR "write", when you change the data in a secondary connection that's a read-only connection it doesn't save the data. Hey, that's kind of like a temporary variable! Constructing the XML file is pretty simple. Here's one that I've used:
<?xml version="1.0" encoding="utf-8"?>
<currentuser>
 <username />
 <preferredname />
</currentuser>
You can't specify type--as far as I can figure out--but most of the time strings are just fine. The advantage of this system is that you can get info about the current user, store it in a field for use, but not have to worry about purging the data before saving the form. This became a huge advantage with our recent userName() debacle.

In January, we launched a new web application on our SharePoint farm that utilized single sign-on and a claims-based authentication. Two major things broke when we tried using a form: accessing web services and the userName() function returned a string I'd never seen. Normally the function would return "jdoe", but in the claims-based environment it returned "i:0#.w|domain\jdoe". This was a huge issue because a lot of our forms compare the current user to some kind of list to determine access. Changing every single rule that used userName() to some unwieldy expression was not sounding fun either. So I devised a new method.

Instead, I used a temporary field and two form load rules. Using the XML example above, I then created two rules in my form load rules.

Click here to return to my listing of "codeless" blog entries. The underlined username is referring to the field in the secondary XML resource.

Rule #1 - current user has slash
Condition: contains(xdUser:get-UserName(), "\")
Action:
  Set a field's value: username = substring-after(userName(), "\")

Rule #2 - current user no slash
Condition: not(contains(xdUser:get-UserName(), "\"))
Action:
  Set a field's value: username = userName()

Now I have a field that will always contain only the username of the current user. The disadvantage of this is where you have fields that set their default value once and used the userName() function. To overcome this problem all you have to do is add a third form load rule that I like to call "First Load".

Rule #3 - First Load
Condition: FormName is blank
Action:
  Set a field's value: FormName = concat(now(), "_", username)

And that's all there is to it. Click here to return to my listing of "codeless" blog entries.

Until next time:
Work smart. Live free.

04 January 2013

codeless: double eval

/TECH
My current job title is SharePoint Developer. However, my work is a lot more specific than that. Yes I develop for SharePoint, but more specifically I develop custom, codeless web forms using InfoPath as my primary design tool. The key here is that everything I do doesn't contain custom code but rather out-of-the-box functionality used creatively. And boy do I get creative. Over the next several blog entries I want to explore some of the codeless designs I've found, developed, and refined.

The first trick I want to talk about is one that I use a ton: the double eval. When I first started developing with InfoPath I found that there were several things I couldn't do that I could in C++. Now, I understand that InfoPath isn't a programming language, but it is based on web-technology and several web languages support. So why the hell can't I systematically grab data from a repeating field?! Well, you can. I remember looking at all the functions I could use in an expression once and when I got to eval(), I had no idea how to use it. Even the description of for using it was cryptic: "Returns a node-set containing the result of the expression for each set of elements in the context field." If you added it to the expression, you got the following template:
eval(double click to insert field, "type expression here")
Now I don't know about you but I learn much more about a function by seeing an example of it being used. I finally saw an example one day of the following expression from Infopath codeless programming (walkthrough) 2:
eval(eval(Person, 'concat(my:AccountId, "|")'), "..")
At first I couldn't figure out what was going on, but after I used it several times in different forms I figured out how the two eval() functions were working together. Let's break this down starting with the inner eval().
eval(Person, 'concat(my:AccountId, "|")')
This eval() is referencing the field Person and then using concat() on it. The trick here is that the concat() function is being run relative to where Person is located. This means that if you need to do a comparison to another field with your concat(), you need to write the xpath as if the concat was running on Person. Say you want to filter AccountId based on Department. If you were to look at the xpath for the two fields you might get something like this:
- MyFields
  - Person
    = AccountId
  = Department
You'll notice that Person and Department are parallel and AccountId is a child of Person. For our concat() above to filter AccountId using Department, it would have to be done like so:
'concat(my:AccountId[../../my:Department = "IT"], "|")'
What this does is back up twice relative to where AccountId is located and then looks for Department. It's really important to know where in the hierarchy an expression is going to run. You may have also noticed that the entire expression for the eval() is enclosed in single quotes, not double quotes. That's because the expression needs to use double quotes to function correctly, thus you change the overall encapsulation to single quotes.
eval(eval(Person, 'concat(my:AccountId, "|")'), "..")
The outer eval is easier to break down and is where the "looping" action actually occurs. The outer eval() is treating the inner eval() as the field it is working on and the ".." as the expression. The unique thing about the expression here is that it is looking for one thing: when the field has to go back or up a level in the hierarchy. As soon as that happens, the outer eval returns the results of the inner eval() that occurred on each instance of Person, in this case, a string of concatenations that results in the output of a single string of text. The output would look something like this:
jcool|cbrown|ppatty|lucyvanpelt|
This is now a really useful way to gather info into a single field for further use and/or processing. I've used it to concatenate the usernames from a SharePoint list to use in a comparison in the form for security, creating a list of approvals still needed, and even doing a sort of "group by" query on a repeating table.

Thanks to Alec Pojidaev and posting that little trick to his blog. It's come in extremely useful. Check out his blog for some other codeless solutions. Click here to return to my listing of "codeless" blog entries.

Until next time:
Work hard. Play harder.

codeless

/TECH
My current job title is SharePoint Developer. However, my work is a lot more specific than that because the I nearly exclusively develop custom, codeless web forms using InfoPath as my primary design tool. The key here is that everything I do doesn't contain custom code but rather out-of-the-box functionality used creatively. And boy do I get creative. Over the next several blog entries I want to explore some of the codeless designs I've found, developed, and refined. To keep things tidy, I'll preface each post title with "codeless" so you know what you're getting into and additionally keep links to all my "codeless" posts here. If you're working with InfoPath, I hope these articles help you.

"codeless" articles:
Until next time:
Work hard. Play harder.

18 December 2012

codeless: expression box/calculated value

/TECH
Have you ever needed to display text that changed depending on other aspects of the current form in question? If you have, perhaps you've already used these. But if you're like me and you didn't see an obvious solution (a rarity in SharePoint and Infopath) you found another way. I personally used sections and text fields to dynamically hide and display text. But this isn't the only way.

I discovered this little feature by accident one day. They're called an Expression Box in 2007 and a Calculated Value in 2010. These incredibly simple controls are part of the form template only, which means the data in them is never stored with the form itself. One disadvantage that I can tell though is that you can't reference them, much like a button control. But if you're already basing the info in the control off of data in the form, you don't need to reference it.

But the thing that bothers me the most is that I've been working with InfoPath for 2.5 years now and never knew about them. If you haven't discovered them yet, go use them cause God knows they're useful.

Until next time:
Work hard. Play harder.

19 November 2012

(re)work

/TECH RANT
Remember last time when I said Doppelganger has the caveat of "subject to change"? Yeah, apparently my work projects also have that. Two weeks ago I was "finishing" a form project only to have a discussion last Monday that made me go, "Oh crap." So my main project for the past month or so has been updating our Cell Phone Allocation form to include the option of getting a phone through the company. Previously you could only get a reimbursement for using your personal phone for business related work. Now, the university is offering full-time employees phones paid for by the university and the employee takes a deduction on each pay check for using the business phone for personal purposes. What I had spaced was the fact that the addition and the deduction were opposite from each other. So in five days I re-worked a significant portion of logic in the form to properly calculate the pay period allocation or deduction.

Five days isn't much, but I managed it. The worst part is because all these changes had to be to the current form, we now need to re-convert the form for our SharePoint 2010 migration. You might think that I should just make the changes to the new form rather than re-convert but I'll tell you now, it'll be faster to re-convert. The changes were extensive and although I just finished working on it, I can't remember everything I did and really need to hand the 2010 version over to a co-worker. So re-conversion it is.

The Cell Phone Allocation form isn't the only one that's been hijacked. So has one of the SharePoint Team's least favorite form: the IRB application. This form has given us numerous problems though most of them can be attributed to user error. However, to attempt to mitigate these issues the form has been updated numerous times since it was converted. Yes, with proper documentation we could probably update the 2010 form without trouble but how often do you have good documentation available? How often do you make good documentation?

I've even been improving our documentation, but it's improvement is secondary to the immediate problems of conversion and troubleshooting. Documentation wasn't always a problem for me. In fact in programming I'm pretty good about commenting code and what-not. But SharePoint and InfoPath documentation are different because they're visual design editors with no way to comment segments. So documentation has to be put in a separate document. Which means if you update something, you have to update the documentation separately. And most of the documentation is done through screenshots of the layout and design.

I apologize to people reading this expecting to see solutions to problems on various systems. Perhaps I should move these rants to my other blog and start posting more technical things here...

Until next time:
Work hard. Play harder.