Last week I bit the bullet and bought the full version of Teamviewer and I already loving it. Having clients do Help > Start Remote Control from my app’s menu (and then my code is simply run / TeamView—-) is worlds easier than directing them to a website to download an EXE.
Today I had a client trying to move my app from one computer to another. They were having trouble as clients sometimes do. I was on the new computer, but needed files from the old computer. So I had the client start remote support on the old computer, while I was still connected to the new computer…. and it worked. I had two sessions of Teamviewer running connecting me to both computers at the same time.
I had them up and running in 10 minutes with no hassle. Pretty slick.
After a couple successful months with the free Teamviewer, I finally bit the ($800) bullet and bought the full version. Yeah, that feels expensive, but I figure it will eventually be cheaper than the monthly or the pay-as-you-go services. :: crosses-fingers ::
One of the nice features of TeamViewer is that it’s a simply EXE that the client runs to start a remote control session (Teamviewer calls it Quick Support). I can distribute this EXE to my clients with my app and call it directly from my VFP app — no walking them through a download from a website, trying to find their download folder, and then getting them to run it. Very easy.
When a user wants support, their name shows up in my TeamViewer admin panel. I just click on that to start the support. Here’s a user named Administrator wanting support:
Another nice touch is that you can customize the program on the client to look how you want. You can add your logo, change the text around, and change the colors. So my clients see this customized version rather than some confusing screen with some other company’s name on it:
And, you can have multiple quick support screens. So one group of clients get the one above, while other clients have this one:
Easy to use, easy to implement to the client, customizable so it looks like my product, and – hopefully – a price tag that breaks even in not too long.
Gotcha: One gotcha to look out for. The EXE you’re sending to your client has a got an ugly name like “TeamViewerQS-en-idXXXXXX.EXE”. If you change that name, it will still work but it won’t show your customized screen. You have to use that file name to get your customized screen.
I’ve pretty much given over everything to Google at this point with two hold outs remaining: OneNote for notes (thanks to the Eric Selje presentation at Southwest Fox) and gQueues for managing tasks/to-dos.
I keep hoping that Google Keep might be able to replace those two things – giving me a little more integration and giving Goole a little more of my soul – but the app is missing a couple key things:
- No text formatting. I could probably live without bold/italics, but Keep’s inability to – for example – let me copy a table from a web page and paste it in is kind of a killer.
- Keep can’t order your notes within a label. Sure, Keep will let you rearrange/order your notes on the main page – where I have a couple hundred personal and business notes – Not convenient. OneNote and gQueues (more importantly for GTD) let me order things within a category. This is a deal breaker.
- gQueues has really smart recurring task settings. The one I use all the time is “repeat this task X days after I complete it” (doing the laundry for example, I need to do that every 7 days or so. I don’t need to do it every Wednesday). Because sometimes I don’t always GTD when I’m supposed to GTD. Keep only has the very dumb “repeat every X days”. I could create a non-recurring task and just continually move it when I’m done, but that’s annoying and doesn’t give you the little dopamine rush of marking it done.
- OneNote has a great web clipper that lets you grab the whole web page, part of the page, can recognize if it’s a recipe and cleans it up, and then ultimately stores the web page all nice and pretty in a note. Keep can only put the link in a note for you. I suppose that’s better than nothing, but it is frequently worthless when I’m trying to search for a recipe and the recipe name isn’t in the link.
So until Keep gets an upgrade (and I have little hope of that. Google seems to release stuff and then be done with it) I’ll keep using OneNote (which is slow, clunky, and doesn’t integrate with my other Google apps) and gQueues (which I actually really kind of love and don’t mind paying the $25 a year for and does integrate nicely with my Google calendar).
Stripe.com has an …interesting… feature where when you ask for a bunch of things – customers, recent charges, etc – it doesn’t return all of them to you, but instead gives you just the first 100. I’d guess it’s a performance issue, but it does mean you have to take a few steps and a few calls when you need all of something.
For example, you can call Stripe to get customers with a call like: /customers. This will only return the first 100 customers to you.
To get the next 100 customers, you have to do a call like /customers?starting_after=<TheIDOfTheLastCustomerYouGotInThePreviousCall>. (And, no, you can’t do customers?starting_after= and leave this blank. Stripe gives you an error for that.)
So to get all your customers, you have to do the first call and then repeatedly do the second call until Stripe tells you there are no more. How do you know when there are no more? One of the last fields Stripe returns to use is “has_more” which is true/false. If there are more records to return, it’ll be true.
And one final gotcha: Stripe doesn’t return a nice neat ID number for those calls. It returns a bunch of data about the customer, and data about their subscription, and data about their plan, and data about their recent charges. So if you’re searching that data looking for the customer ID, you have to make sure you’re looking in the right place and not getting a Subscription ID by mistake. Additionally, there can be multiple has_more entries in there for that extra stuff. Make sure you’re looking at the right one.
The CustomerList function of the StripeX wrapper is a good example of how to make all of this work.
Ran into this rather bizarre problem with a client today. They have a lovely merge document that my program creates for them in Word. It has a header that looks like this:
In some cases, the user will go in and make changes to this document after it’s created. They might delete the last couple paragraphs for example. When they do that, the header in the document will suddenly turn to this:
The merged data disappears and Word reverts to merge fields!
Googling “deleting lines in Word document causes merged data to revert to a merge field” didn’t turn up anything.
Playing around with it, I discovered that it only happened if you deleted to the very end of the document. Curiously, at the end of the document was a single, invisible character. As long as that isn’t deleted, the merged data stays put.
The QuickPDF tool from Debenu can do a lot – read PDFs, modify existing ones, create new ones line by line, and lots more.
I had a client that was receiving a bank statement as PDF that we needed to input the info to their Foxpro system. With QuickPDF I could read through the PDF file, convert it all to text, and then process the text to do my import. Pretty powerful and pretty easy.
Here’s a sample program that will convert a PDF to a text file using QuickPDF:
Rick Borup‘s excellent sessions at Southwest Fox has gotten me using Mercurial in my development. One thing Rick didn’t cover (or maybe I just missed it?) is that you can create a global hgignore file in Mercurial. If you’re working with multiple projects, that’s incredibly handy. You setup the global file just once and it’s used for any repository you have.
You’ll find the global file in My Documents and it’s named hgignore_global.txt. Put all of the standard stuff you want ignored – VFP binaries, *.zip, etc. – in this file and then you won’t have to set that up every time you create a new repository. (Rick has provided a good baseline hgignore in previous Mercurial sessions. Doug Hennig provided one as well in his ‘Lessons Learned with Version Control’ session in 2016.)
The global file works in conjunction with the local .hgignore file – Mercurial will ignore anything that is contained in either file when you attempt a commit. So if one project has some special things to ignore, you just add them to the local hgignore.
Lastly, if you’ve got one strange repository that needs to ignore the global hgignore entries? Mercurial can do that as well.