tag:blogger.com,1999:blog-58818074580992470132008-05-05T16:30:45.779-04:00Cathy PountneyCathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comBlogger21125tag:blogger.com,1999:blog-5881807458099247013.post-49381260291527335302008-05-05T16:16:00.004-04:002008-05-05T16:30:45.858-04:00Problems with Code Sector - Direct Folders - Round 2Wow ... what can I say other than, I'm shocked at the appalling behavior of this company.<br /><br />In my previous blog post, I explained that this company has been less than responsive in my request for help because the product did not perform properly on Vista. I eventually asked for a refund and they were also non-responsive to that too. After posting that blog I sent a link to the company so they could see the bad publicity their behavior was generating. I received a comment on the blog stating:<br /><br /><em>"This problem was resolved on March 27, I'm sorry I forgot to let you know. You may download Direct Folders 3.31 or make a refund request at Plimus website".</em><br /><br />Hmmm .. it's now May 5 and they "forgot" to inform me of the newer version, despite my repeated attempts to contact them and ask them when the new version was available. That didn't sit right with me so I decided I didn't want software from this company on my machine and I would just ask for a refund (yet again). Here's the reply I just got from them:<br /><br /><em>Dear Cathy,<br /><br />Refunded. Next time test software before purchasing.<br /><br />Best regards, Jeff</em><br /><br />Whoa! Someone woke up on the wrong side of the bed!!! I'm shocked at what a snotty reply they sent me. I guess this just confirms that I don't want software from this company on my machine!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-82580102231026757122008-05-03T16:21:00.002-04:002008-05-03T16:30:29.527-04:00Problems with Code Sector - Direct FoldersBack in February, I purchased a product called Direct Folders from Code Sector based on a recommendation of a colleague. This utility is supposed to provide an easier way to manage your folders. Unfortunately, that's not what happened for me.<br /><br />I'm running Vista so I made sure the product was Vista compatible before purchasing. Their website said it was. So far, so good. I bought the product and installed it. So far, so good. Then I started using it .. not so good. Apparently, it only works correctly on Vista if you're running in Admin mode .. which I'm not! The "configuration" option is not accessible without Admin rights, yet that is the option that you're supposed to use to set the tool up to work the way you want. Kinda hard to set it up if you can't run the "Config" option!<br /><br />I contacted product support and they told me they were working on a version that's more compatible with Vista. OK .. I can wait a little while .. but how long is a little while. I repeatedly asked them WHEN this newer version will be available and they never replied to any of my requests. After a month I got disgusted and uninstalled this product from my machine. I then asked them for a refund, explaining the problem. Again, I have gotten no responses from them despite repeated attempts to ask for a refund.<br /><br />So apparently this company only responds when you're buying the product. Anything negative and they pretend they didn't hear you! BUYER BEWARE!!!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-60566826251589599152008-04-15T14:33:00.012-04:002008-04-15T16:53:04.468-04:00How Do I ... Total fields for one detail band onlyWhen multiple detail bands were introduced to Visual FoxPro it was a great addition that was long overdue. However, there's one aspect of that feature that wasn't clearly thought through and that's Calculations and Report Variables.<br /><br />Let's say you create a report with multiple detail bands. Then you add a data group to the report and in the data group footer you add some fields that are defined to calculate using the SUM option. The problem that can arise is the calculation is applied to every record in <strong><u>both</u></strong> detail bands and maybe you only want to sum the records in the first detail band. Hmmm ... now what?<br /><br />There's a workaround, but it takes some extra work on your part. Start by defining a Report Variable called rnDetail; Set the Value to Store to 0; Set the Initial Value to 0; Set the Reset option to End of Report; and set the Calculation option to Sum. This creates a Report Variable that the Report Engine doesn't ever change but now you have something you can manipulate.<br /><br />The next step is to make sure each of the detail bands are marked to include the associated header and footer bands. In the OnEntry Expression of the Detail Header 1 band, enter the expression: _VFP.SetVar('rnDetail', 1). In the OnEntry Expression of the Detail Header 2 band, enter the expression: _VFP.SetVar('rnDetail', 2). These two expressions reset the Report Variable to 1 or 2 at the beginning of the respective detail band so now you have a way to know which detail band you are on.<br /><br />The next step is to create Report Variables for each of the fields you want to sum. For example, if you want to sum the Qty and Price in the first Detail Band, create a Report Variable called rnQty and set the Value to Store to IIF(rnDetail = 1, Qty, 0). Create another Report Variable called rnPrice and set the Value to Store to IIF(rnDetail = 1, Price, 0). Leave the Calculation option of both variables at the default of None.<br /><br />The final step is to add the field objects to the data group footer band. Instead of using the name of the field such as Qty or Price, use your new Report Variables of rnQty and rnPrice for the expression. Set the Calculation options to reset at the data group. Now you have some calculations in the data group footer that only contain values from the first data detail band.<br /><br />This concept can be used in various situations when you need to create calculations or Report Variables that only get processed on one of many detail bands. Once you have the rnDetail Report Variable in place, you can reference it as needed. Just be sure this Report Variable is at the top of the list of Report Variables before any other Report Variables that need to access it. The Report Engine processes the Report Variables in the order they appear in the list.Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-28534552205067568502008-03-17T20:04:00.002-04:002008-03-17T20:38:27.869-04:00Happy St. Patrick's DayI just had to take a moment today and blog about what a special day St. Patrick's Day means to me. No, I'm not Irish. No, I don't drink green beer. No, I don't really party much at all. So what's so special about this day?<br /><br />Today marks the 26th anniversary of my life as a computer programmer!<br /><br />I've been so blessed to have a career I enjoy and didn't want the day go by without saying so! It's actually quite ironic how I ended up in this career. During high school I was a shy, quiet, and very introverted girl (I know .. most of you can't believe that .. but it's true .. I swear!) I was looking for a career where I didn't have to socialize with people too much. We had an assembly at school where the administration talked about the "Career Center". This was a facility where Juniors and Seniors from high schools around the area could spend half their school day learning a career. There were programs for Auto Mechanics, Small Engine Repair, Cosmetology, and lots of other careers.<br /><br />My mom really urged me to consider going to the Career Center. I resisted, but she's pretty persuasive. I considered the Accounting program because I really enjoyed my recent accounting class. I also considered the Engineering class because I really enjoyed my recent drafting class. My mom looked the brochure over and had this to say…<br /><br />“I think you should consider this Computer program. I think computers are really going to take off in the future.”<br /><br />Like I said, my mom is really persuasive so even though I had never touched a computer and didn’t know anything about them, I followed her recommendations. What can I say but, “Thanks Mom!” She was so right about the future of computers. She was also so right about the career choice for me.<br /><br />I have loved being a programmer from the first day I started. It’s been a wonderful ride that has taken me many places. I have enjoyed the fact that to program an application for a business, I have to learn all about that business. I’ve had the opportunity to learn about so many different industries that I probably wouldn’t have ever known about. And the opportunity to work at Microsoft as a contractor was a dream come true!<br /><br />I have also enjoyed the ironic affect this career has had on my life. I’m no longer the quiet, shy, introverted little girl. I’ve come out of my shell and now speak at user groups and conferences as often as I can. I write articles, post on newsgroups, and participate in the FoxPro community as much as possible. So to the entire FoxPro community .. I want to say thanks for the wonderful place you have helped my career go.<br /><br />And I also owe a big “Thanks” to my Mom. She’s one special lady!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-56927365027521907682008-03-12T17:27:00.002-04:002008-03-12T17:32:26.518-04:00Cool Tool: Beyond Compare + Addon by Frank PerezBeyond Compare is a great little utility that can be used to compare files. It's from Scooter Software and is only $30. What makes this utility even cooler is an addon written by Frank Perez (which is $FREE.) He wrote a utility that lets us compare FoxPro files ... like classes, forms, reports, and such. This is awesome ... I can't tell you how many times I have wanted to compare two different reports to see what is different!<br /><br />Way to go Frank!!!<br /><br />Read all about this on Frank's blog at <a href="http://www.pfsolutions-mi.com/blog/2008/03/08/BeyondCompare.aspx">http://www.pfsolutions-mi.com/blog/2008/03/08/BeyondCompare.aspx</a>. I have added links in my Cool Tools section to Beyond Compare and to Frank's site for downloading the addon.<br /><br />Enjoy!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-77957687057686879142008-03-02T08:05:00.003-05:002008-03-02T08:23:05.241-05:00Call to Action - Install VFP 9 SP2Rick Schummer just blogged a compelling call to action for everyone to install VFP 9 SP2 and test it. He took the time to write a whitepaper that explains how to install SP2 in a different directory than your VFP 9 RTM (Release to Manufacturing) or VFP 9 SP1 versions. This way you can leave your production version (RTM or SP1) as is, yet still have SP2 on the same machine so you can test your applications.<br /><br />I can tell you that I had already previously followed his advice and have SP1 and SP2 running on my machine without any problems. I encourage everyone else to do the same. Rick did a great job in explaining why you should do this so I'm just going to point you to his blog which also has the link to his whitepaper.<br /><br /><a href="http://rickschummer.com/blog/2008/03/vfp-9-rtmsp1sp2-one-machine.html">http://rickschummer.com/blog/2008/03/vfp-9-rtmsp1sp2-one-machine.html</a><br /><br />Please take the time to install and test SP2. If we all do this, the entire FoxPro Community, including yourself, will benefit!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-30745195932650408722008-02-18T14:46:00.001-05:002008-02-18T14:46:56.609-05:00A Plumber Who Preys on the NaiveSaturday evening I walked downstairs to do some laundry and stepped into a pool of water. My focus then turned to see water spewing out the relief valve at the top of my water heater. I quickly assessed the situation and saw the shut off valve in the pipe leading to the water heater. I turned it off and that stopped the water from spewing. Then I grabbed my steam cleaner and started soaking up the water. As I was doing so, I thought, “Great! This just tops off a day that has already been full of negative energy.”<br /><br />Once I got the situation under control I called a neighbor and asked for a recommendation for a plumber. Unfortunately, that plumber doesn’t work after hours, so I had to resort to the yellow pages. I had to call about 5 plumbers before I found one that worked on Saturday evening. The Plumbing Connection, whose tagline says, “Happy Today or You Don’t Pay”, said they could be here in about 90 minutes. <br /><br />The plumber arrived as promised and I escorted him to the basement. He walked over to the water heater, read the tag on the front, then looked at me and said, “Is there a place we can sit down and talk?”. OK .. this is where my radar goes off and says this guy is gonna try to scam me. We sit down and he starts his “sales pitch” trying to convince me that his company is like no other and he’s my best friend. Of course, I wasn’t buying into this and the more my body language showed I was disgusted, the more he kept talking trying to win me over. <br /><br />After about 5 minutes I couldn’t take it anymore. I interrupted him and said, “Look, I feel like I’m getting scammed right now. Get to the point and tell me what’s wrong and what’s it gonna cost me to get it fixed. This is where he pulls out a form and asks me to sign next to the part that says I agree to pay $99 for a diagnostic service fee. “No, I’m not signing anything .. you haven’t diagnosed anything yet.” He and I went back and forth about 4 or 5 times on this issue, but I held firm on my stance. I’m not signing anything. The guy hasn’t even picked up a wrench or touched my water heater. How can he claim he’s “diagnosed” anything?<br /><br />Now I’m really disgusted .. and he’s frustrated that I’m not turning out to be the easy target he hoped. He then unfolded the rest of the form and exposed a list numbered from 10 down to 1. Each item had a paragraph describing a service and a price, with the 10 being the highest price around $1000-$1200. He used his pen and slowly scanned down the list trying to determine how much he could bilk me for. He stopped at number 6, circled a price, and then realized that my body language was saying, “No way!” Then he quickly back peddled and said, “Oh, that’s wrong”, as he crossed it out and continued scanning down the page and circled number 4. <br /><br />He then began to tell me that he could replace the relief valve, which is a “level 4” service that costs $199. Of course, this is on top of the $99 he wants to charge me for coming to the house and diagnosing the problem. The hairs on the back of my neck are standing up right about now. “However”, he says, “I don’t think that will fix your problem. You need a new water heater.”<br /><br />This is where I stood up, looked him straight in the eye and said, “Get out of my house!” He was in shock. How could I order him to leave? He hasn’t fixed anything yet. I need him. I’m just a woman. I can’t fix this on my own. I have to let him fix this. He tried to salvage this ordeal but I wouldn’t let him continue talking and I again ordered him to leave my house. He then said, “OK. Just pay me the $99 and I’ll leave.” <br /><br />Um … not a chance pal. I again looked him in the eye and told him, “There’s no way I’m paying you a dime to come into my house and try to scam me. Get out!” He stomped into the other room, grabbed his tools, and started walking up the stairs. But he tried one more time to salvage this service call. He tried to explain to me that he read the tag to see how old my water heater was. He then tried to explain that water heaters start leaking around 10 years old and mine is older than that. Once again, I cut him off, snapped my fingers and pointed to the top of the stairs and ordered him out. He stormed out. <br /><br />I have no tolerance for people trying to scam me. This guy had no intentions of ever trying to fix my water heater. He walked into my house will full intentions of selling me a brand new water heater which I’m sure would have been the “Level 1” price of over $1000. This guy preys on the naïve and probably scams women and older people all the time. It’s disgusting.<br /><br />In the morning I made a few more phone calls to my stepdad and dad for some advice. They both seemed to think I could handle this myself. After all, I have tools and I know how to use them! I’ve repaired electrical stuff, I ran cable through my house, I’ve done a lot of remodeling work, and I even built a two-story shed. So I grabbed a bucket and started draining the water heater hoping that maybe there was some crud in the tank that was causing a problem. Nope .. all the water was a clear as could be. <br /><br />Okay, on to plan B. I grabbed a wrench, took off the relief valve, and drove to Lowe’s to get a new one. Then I came back home, installed the new valve, and turned on the shut off valve so the tank would fill back up with water. Once filled, I lit the pilot, and stood back and crossed my fingers. Success!! The water heated and when it hit the target temperature, the flames turned off. No water spewed out the top!<br /><br />• Having a crooked plumber walk through my door … $99<br />• Having a crooked plumber fix a relief valve … $200<br />• Having a crooked plumber sell me something I didn’t need … over $1000<br />• Fixing it myself with a $13 part … Priceless!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-71397285123107438682008-01-27T14:33:00.000-05:002008-01-27T14:41:23.086-05:00FoxPro User GroupsThe value of FoxPro User Groups is tremendous. I've learned so much from them, made so many contacts, improved my skills, learned about many third-party & productivity tools, made lots of friends, and even obtained a job through them. <br /><br />Sadly, FoxPro User Groups are a dying breed. Our local group (GRAFUG - Grand Rapids Area FoxPro Users Group) is struggling to stay alive. Attendance has dropped and we're trying to figure out how to attract more people. The core people that attend each month don't want to let it go. We consider the meetings extremely valuable, and a resource that must be kept. We'd like to "market" the group and make sure all FoxPro developers in our area are aware of the group. <br /><br />I'm asking for suggestions from everyone on places to post a blurb about our group in hopes of attracting new attendees. If you're running a successful FoxPro User Group, I'd like to hear from you too. What do you do to advertise the group. I'm looking for any and all ideas on how to boost our local user group and keep it alive!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-46718483149603781752008-01-19T15:45:00.000-05:002008-01-19T15:58:58.203-05:00They Stole My Idea!I'm all about efficiency, and many of you that know me have heard me talk about my "invention" to help me be more efficient. It seems I can never find time to exercise, even though I have a treadmill and a home gym in my house. My invention was to build a desk that attaches to my treadmill so that I can work on the laptop at the same time I'm walking. Think about it .. I have a wireless internet connection .. my printer is hooked up through the wireless connection .. so I have everything I need. It's a great idea and it really works well. At first I thought there might be too much vibration, but it turns out that the desk I built is very stable. I just have to remember to put wrist bands on so the sweat doesn't run onto my keyboard.<br /><br />So, a while back Craig Berntson sent me a link to a treadmill desk for sale on the market. There wasn't much information, and nowhere was a price. You had to send away for information, which always leaves me thinking the price is way too much.<br /><br /><a href="http://bp2.blogger.com/_sEWO0rxzjkk/R5JjNAReK3I/AAAAAAAAAHU/f7Igc06Pop0/s1600-h/Steelcase+Walkstation.jpg"><img id="BLOGGER_PHOTO_ID_5157293598355368818" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://bp2.blogger.com/_sEWO0rxzjkk/R5JjNAReK3I/AAAAAAAAAHU/f7Igc06Pop0/s400/Steelcase+Walkstation.jpg" border="0" /></a><br />Move forward to last night when I was reading the recent issue of Reader's Digest. They have an article called "The New Slow Burn At Work" and it shows a picture of a treadmill desk offered by Steelcase called "The Walkstation". Now for those of you that don't know, western Michigan is known for furniture manufacturers. Steelcase, Herman Miller, and Haworthe are all here. I think a spy overhead me talking about this idea and ran back to their boss at Steelcase and presented the idea as their own. <br /><br />I will admit their version looks much more professional than mine and offers more workspace. However, it comes with a price tag of $4000. Mine cost me less than $500 for the treadmill and the desk combined!! <br /><br />I should have patented the idea! Darn .. my financial independence has been dashed again!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-10139184314717199362008-01-13T13:30:00.000-05:002008-01-13T13:34:02.261-05:00Press Release: MBS attains Microsoft Certified Partner statusMemorial Business Systems, Inc. (MBS) has attained Certified Partner status in the Microsoft Partner Program. To become a Certified Partner, MBS had to demonstrate expertise with Microsoft technologies and demonstrate its ability to meet customers’ needs with exceptional expertise. Microsoft Certified Partners receive a rich set of benefits, including premier access, special training, and the highest levels of support, giving partners a real technologically competitive advantage.<br /><br />Memorial Business Systems’ software and services are designed to improve the operational efficiency and effectiveness of cemetery and combo operations. MBS software represents the leading edge of technology ensuring against customer obsolescence.<br /><br />“We are obviously pleased to have attained Certified Partner status. This is confirmation that our software is advantageous for cemeteries at all levels and as flexible and easy to use as we say they are,” said Fred Miller, President of MBS. “We put out products that work from the get-go, and our customers are clearly appreciative. Our developmental talent gets the credit.”<br />“Microsoft recognizes MBS as a new Certified Partner for demonstrating its expertise in providing customer superior satisfaction using Microsoft products and technology.” said Allison Watson, corporate vice president of the Worldwide Partner Group at Microsoft Corp.Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-83970469900027227052008-01-01T21:38:00.000-05:002008-01-01T21:46:20.517-05:00How Do I ... Create some complicated data groups and build a recap?I recently had to create a very complicated report for a client that covers several different techniques. I thought it would be good to share this modified sample with everyone.<br /><br />At first, the report sounded simple (don't they all!) Create a list of orders, sorted and subtotaled by customer and each customer should start on a new page. That's easy, I can handle that. Put the orders in the detail band. Create a data group on the Customer and mark it to start on a new page. Put subtotals for the customer in the Data Group Footer band.<br /><br />Oh .. the client says .. the list of orders per customer can get quite long. Can we have ledger-style shading or a line every so many lines? Sure, I think I can handle this. Oh ... the client says again ... we'd also like subtotals at the bottom of each page showing the totals of just that page. That should be easy .. I can use the page footer band. Oh wait .. as I think that through some more, it's not going to work because on the last page for the customer, the data group footer band would print and then the page footer would show up at the bottom. That's not cool. Hmm ... these two requirements combined make things a little sticky .. but I'm sure I can come up with the answer.<br /><br />Then comes the killer requirement .. Remember those page subtotals we want at the bottom of each page .. well .. at the end of the customer we'd also like a recap that shows each one of those subtotals like the following:<br /><br />Page 1, $999.99<br />Page 2, $999.99<br />Page 3, $999.99<br /><br />Yuk .. I really don't like that one especially combined with the ledger-style and page subtotals. Now I'm really going to have to put some thought into this report. I think my head is spinning!<br /><br />For this example, I'm using VFP 9 SP2 (although it should work with previous versions because I'm not using a ReportListener or any of the new features.) I'll use the TasTrade data stored in C:\Program Files\Microsoft Visual FoxPro 9\Samples\Tastrade\Data. I wanted to be flexible with the number of lines per ledger section and the number of lines per page so I decided to control them with a variable. That way, if the customer changes their mind down the road I can easily change it.<br /><br />I also didn't want to mess around with trying to build the data for the recap ahead of time. Again, I was thinking down the road about using this technique for other situations and if I were to use it on a report with stretchable fields, I didn't want to use hard-coding to "count" each record and figure out the appropriate page it falls on. I just wanted to let it flow and let the report build the recap data for me no matter how many records appeared on a page. I also didn't want to have to hard-code all the variables to be totaled. I wanted some generic code that totals all the numeric or currency fields.<br /><br />Let's start by looking at the final report as shown below in Figure 1. The first page shows the records for the first customer. The second page shows the "recap" for that customer, which only contains one page. The third and fourth pages do the same thing for the second customer. The fifth through seventh pages show the details for the third customer and the last pages shows the "recap" of each of the three previous pages which belong to the third customer.<br /><br /><a href="http://bp3.blogger.com/_sEWO0rxzjkk/R3rmkQReKuI/AAAAAAAAAGM/Glpeyg7WW48/s1600-h/ComplexGroups_Recap_Page1.jpg"><img id="BLOGGER_PHOTO_ID_5150682634369510114" style="CURSOR: hand" alt="" src="http://bp3.blogger.com/_sEWO0rxzjkk/R3rmkQReKuI/AAAAAAAAAGM/Glpeyg7WW48/s400/ComplexGroups_Recap_Page1.jpg" border="0" /></a><br /><a href="http://bp1.blogger.com/_sEWO0rxzjkk/R3rmwwReKvI/AAAAAAAAAGU/YrlpBWvX870/s1600-h/ComplexGroups_Recap_Page2.jpg"><img id="BLOGGER_PHOTO_ID_5150682849117874930" style="CURSOR: hand" alt="" src="http://bp1.blogger.com/_sEWO0rxzjkk/R3rmwwReKvI/AAAAAAAAAGU/YrlpBWvX870/s400/ComplexGroups_Recap_Page2.jpg" border="0" /></a><br /><a href="http://bp1.blogger.com/_sEWO0rxzjkk/R3rm1wReKwI/AAAAAAAAAGc/YbIC8RsNQiU/s1600-h/ComplexGroups_Recap_Page3.jpg"><img id="BLOGGER_PHOTO_ID_5150682935017220866" style="CURSOR: hand" alt="" src="http://bp1.blogger.com/_sEWO0rxzjkk/R3rm1wReKwI/AAAAAAAAAGc/YbIC8RsNQiU/s400/ComplexGroups_Recap_Page3.jpg" border="0" /></a><br /><a href="http://bp3.blogger.com/_sEWO0rxzjkk/R3rm6QReKxI/AAAAAAAAAGk/R9CWNR4s5hQ/s1600-h/ComplexGroups_Recap_Page4.jpg"><img id="BLOGGER_PHOTO_ID_5150683012326632210" style="CURSOR: hand" alt="" src="http://bp3.blogger.com/_sEWO0rxzjkk/R3rm6QReKxI/AAAAAAAAAGk/R9CWNR4s5hQ/s400/ComplexGroups_Recap_Page4.jpg" border="0" /></a><br /><a href="http://bp0.blogger.com/_sEWO0rxzjkk/R3rm-gReKyI/AAAAAAAAAGs/kiWnI41VUSQ/s1600-h/ComplexGroups_Recap_Page5.jpg"><img id="BLOGGER_PHOTO_ID_5150683085341076258" style="CURSOR: hand" alt="" src="http://bp0.blogger.com/_sEWO0rxzjkk/R3rm-gReKyI/AAAAAAAAAGs/kiWnI41VUSQ/s400/ComplexGroups_Recap_Page5.jpg" border="0" /></a><br /><a href="http://bp0.blogger.com/_sEWO0rxzjkk/R3rnDgReKzI/AAAAAAAAAG0/8HMW0wC6EfY/s1600-h/ComplexGroups_Recap_Page6.jpg"><img id="BLOGGER_PHOTO_ID_5150683171240422194" style="CURSOR: hand" alt="" src="http://bp0.blogger.com/_sEWO0rxzjkk/R3rnDgReKzI/AAAAAAAAAG0/8HMW0wC6EfY/s400/ComplexGroups_Recap_Page6.jpg" border="0" /></a><br /><a href="http://bp1.blogger.com/_sEWO0rxzjkk/R3rnHwReK0I/AAAAAAAAAG8/QIgkMMYxSHA/s1600-h/ComplexGroups_Recap_Page7.jpg"><img id="BLOGGER_PHOTO_ID_5150683244254866242" style="CURSOR: hand" alt="" src="http://bp1.blogger.com/_sEWO0rxzjkk/R3rnHwReK0I/AAAAAAAAAG8/QIgkMMYxSHA/s400/ComplexGroups_Recap_Page7.jpg" border="0" /></a><br /><a href="http://bp3.blogger.com/_sEWO0rxzjkk/R3rnLQReK1I/AAAAAAAAAHE/hSD0JH18o2Q/s1600-h/ComplexGroups_Recap_Page8.jpg"><img id="BLOGGER_PHOTO_ID_5150683304384408402" style="CURSOR: hand" alt="" src="http://bp3.blogger.com/_sEWO0rxzjkk/R3rnLQReK1I/AAAAAAAAAHE/hSD0JH18o2Q/s400/ComplexGroups_Recap_Page8.jpg" border="0" /></a><br /><i>Figure 1: The final printed report.</i><br /><br />Next, let's look at the simple program that I use to create the data and print the report. Notice that I use two variables to control the groupings. I could have hard-coded this in the report itself, but this is more flexible.<br /><span style="font-family:courier new;"><span style="color:#666666;"><pre><br />*-- Build the data<br />SELECT '1' AS RecType,<br /> Orders.Customer_ID, ;<br /> Customer.Company_Name, ;<br /> Orders.Order_Number, ;<br /> Orders.Order_Date, ;<br /> CAST(Orders.Discount AS N(14,2)) AS Discount, ;<br /> CAST(Orders.Freight AS N(14,2)) AS Freight, ;<br /> CAST(NVL(SumLines.nPrice, 0) AS N(14,2)) nPrice ;<br /> FROM 'C:\Program Files\Microsoft Visual FoxPro 9\Samples\Tastrade\Data\Orders' ;<br /> LEFT OUTER JOIN 'C:\Program Files\Microsoft Visual FoxPro 9\Samples\Tastrade\Data\Customer' ;<br /> ON Customer.Customer_ID = Orders.Customer_ID ;<br /> LEFT OUTER JOIN ;<br /> (SELECT OrdItems.Order_ID, ;<br /> SUM(OrdItems.Unit_Price * OrdItems.Quantity) AS nPrice ;<br /> FROM 'C:\Program Files\Microsoft Visual FoxPro 9\Samples\Tastrade\Data\OrdItems' ;<br /> GROUP BY OrdItems.Order_ID ;<br /> ) SumLines ;<br /> ON SumLines.Order_ID = Orders.Order_ID ;<br /> INTO CURSOR tmpReportData READWRITE<br /><br />*-- Index the data<br />SELECT tmpReportData<br />INDEX ON Customer_ID + RecType + Order_Number TAG SortKey<br />GOTO TOP<br /><br />*-- Set some variables to control # of lines<br />*-- for each section and # of lines per page.<br />nMaxLinesPerLedger = 2<br />nMaxLinesPerPage = 6<br /><br />*-- Run the report<br />REPORT FORM ComplexGroups_Recap TO PRINTER PROMPT PREVIEW</pre></span></span><br />Besides the above program, I also need a function that I'm going to call from the report itself. This function will update the cursor that is driving the report by either adding a new record for a particular page, or adding to the numeric fields for the given page. Note that I have to take great care to move the record pointer back to where it was when this function was called. Otherwise, you'll make a mess of the running report. Add the following function to the bottom of the program that runs the report so it's available to the report.<br /><span style="font-family:courier new;"><span style="color:#666666;"><pre><br />************************<br />FUNCTION AddToPageTotals<br />************************<br />LPARAMETERS tcField, txPage, tcSeek, tcIndex<br /><br />LOCAL loRecord, lnRecNo, lcAlias, lcSeek, lx<br /><br />*-- Don't do this on the total records themselves!<br />*-- (Can you say "infinite loop")<br />IF RecType = '2'<br /> RETURN<br />ENDIF<br /><br />*-- Remember where we are<br />lnRecNo = RECNO()<br />lcAlias = ALIAS()<br /><br />SCATTER NAME m.loRecord<br />m.loRecord.RecType = '2'<br />m.loRecord.&tcField = txPage<br /><br />lcSeek = EVALUATE(STRTRAN(m.tcSeek, 'XTMPX', 'm.loRecord'))<br />IF SEEK(m.lcSeek, m.lcAlias, m.tcIndex)<br /> *-- add the amount fields to the existing record<br /> lnFields = AFIELDS(laFields)<br /> FOR ln = 1 TO lnFields<br /> lcField = laFields[m.ln, 1]<br /> lx = EVALUATE(m.lcField)<br /> IF VARTYPE(lx) $ 'NY'<br /> REPLACE (m.lcField) WITH NVL(EVALUATE(m.lcField),0) + NVL(m.loRecord.&lcField,0)<br /> ENDIF<br /> ENDFOR<br />ELSE<br /> *-- Add the record for this page<br /> INSERT INTO (m.lcAlias) FROM NAME m.loRecord<br />ENDIF<br /><br />*-- Go back to the "detail" record that we were processing<br />GOTO m.lnRecNo</pre></span></span><br />Now let's get to the definition of the report, which is the meat of this solution. Figure 2 shows how the report definition will look when we're done.<br /><br /><a href="http://bp0.blogger.com/_sEWO0rxzjkk/R3r6NgReK2I/AAAAAAAAAHM/eKpXrwDPX8I/s1600-h/ComplexGroups_Recap_FRX.jpg"><img style="cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_sEWO0rxzjkk/R3r6NgReK2I/AAAAAAAAAHM/eKpXrwDPX8I/s400/ComplexGroups_Recap_FRX.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5150704233760041826" /></a><br /><i>Figure 2: The report definition.</i><br /><br />Start by creating 3 report variables:<br /><ul><li>rnLinesOnPage</li><br /><ul><li>Value to Store = 0</li><li>Reset = Report</li><li>Calculation Type = Count</li></ul><br /><li>rnLinesForCustomer</li><br /><ul><li>Value to Store = 0</li><li>Reset = Report</li><li>Calculation Type = Count</li></ul><br /><li>Dummy</li><br /><ul><li>Value to Store = AddToPageTotals('Order_Number', TRANSFORM(_PageNo, '999999'), 'XTMPX.Customer_ID + XTMPX.RecType + XTMPX.Order_Number', 'SortKey')</li><li>Reset = Report</li><li>Calculation Type = None</li></ul></ul><br />At first thought, it might look like I made a typo above because none of the variables reset at the Customer group or Page group. But trust me .. it's not a mistake. Just bear with me and it will make sense soon.<br /><br />The last variable is used to call the function we created earlier. It looks a little complex but that's just because I made the function generic so I can reuse it on other reports. You could simplify it by taking away all the parameters and hard-coding the function.<br /><br />Next, create 4 different Data Groups:<br /><ul><li>1: Customer_ID, New Page Number 1, Reprint group header on each page</li><br /><li>2: RecType, New Page</li><br /><li>3: INT(rnLinesForCustomer / nMaxLinesPerPage), New Page</li><br /><li>4: INT(rnLinesOnPage / nMaxLinesPerLedger)</li></ul><p></p><br />Expand the #1 Data Group Header band and put the Customer field.<br /><br />Put the detail fields in the Detail band and lay them out as you desire.<br /><br />Expand the #4 Data Group Header band and add a horizontal line to separate the chunks of detail records. I made my light gray so it's not so distracting.<br /><br />Expand the Data Group Footer bands for #3 and #4 so you can add some totals. Copy your numeric fields from the Detail band into the two different group footer bands. Next, change the Calculate option on each to SUM and reset on the applicable group.<br /><br />Now go ahead and add whatever column headings you want. You can use Print When logic of RecType = '1' if you want to print something for just the regular data. Use RecType = '2' if you want to print something on just the page recaps.<br /><br />At this point you might think we're done, but we're not. Remember when we defined the report variables I mentioned that we are not resetting them at the appropriate data groups. The reason is that whenever you try to alter the variable that is being used to control the groups, the VFP Report Writer gets completely confused. You end up with more breaks than you want and often times you get pages with no detail records and just some totals.<br /><br />So here's the trick behind this whole report. We need to reset the report variables ourselves. Well, actually, we aren't resetting them, we're fudging them. The problem is that if we reset them to zero, we get the extra breaks I just mentioned. So instead of resetting them to zero, we fudge them to a value that makes the next page start at a clean point.<br /><br />We are going to alter these variables in the On Entry and On Exit Expressions of the #2 Group Footer band as follows:<br /><br />On Entry: _VFP.SetVar('rnLinesForCustomer', rnLinesForCustomer- MOD(rnLinesForCustomer, nMaxLinesPerPage))<br /><br />The above "expression" resets the rnLinesForCustomer variable to a value that is equal to what the count would be if the page was completely full of lines, without resetting it for each page. So if we allowed 10 lines per page, at the end of the first page we reset it to 10, at the end of the 2nd page we reset it to 20, and so on. Regardless of how many lines actually printed, we just make it think that full pages have been printed. By doing this, we avoid the funky extra breaks that happen when you try to zero out the variable.<br /><br />On Exit: _VFP.SetVar('rnLinesOnPage', rnLinesOnPage- MOD(rnLinesOnPage, nMaxLinesPerLedger))<br /><br />The above "expression" does the same thing for the ledger breaking as the previous one did for the page breaking. It really doesn't matter which one is in the On Exit and which one is in the On Entry. I just needed to reset two variables and this gave me a place to do each one.<br /><br />That's it. We're done. Simple, right? Well .. of course it's simple when you already know the answer. Trust me .. it wasn't that simple for me to come to this conclusion, but now you can benefit from my troubles. If you want the sample program and report I used to create this blog, just send me an email and I'll gladly send it to you.Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-50352307913034635942007-12-28T15:44:00.000-05:002007-12-28T15:47:13.965-05:00New VFP Magazine Announced!Rather than retype what Rick Schummer did ... here's a link to his blog describing the new magazine by Rainer Becker:<br /><br /><a href="http://rickschummer.com/blog/2007/12/fox-rocks-with-foxrockx.html">http://rickschummer.com/blog/2007/12/fox-rocks-with-foxrockx.html</a>Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-71996813279107125222007-12-07T09:08:00.000-05:002007-12-07T14:58:51.099-05:00Gotcha: Dangling Datasession Left After Running ReportIf you run a report using a ReportListener from the FFC directory, and you're using a successor listener, and that report is run from a form with a private datasession, you end up with a dangling datasession after the report completes. If you keeping running reports in this manner, you keep building up more dangling datasessions. I don't think I have to tell you the consequences of a long day of running reports like this!<br /><br />I posted this on Microsoft's Connect site so anyone who wants to confirm, vote, comment, etc. about this bug, the ID number is 316134.<br /><br />Here are the steps to reproduce the problem:<br /><br />1. Create a form<br />2. Set the datasession to private<br />3. Add a button with the following code in the click<br /><br /><span style="font-family:courier new;"><span style="color:#666666;">lcReport = SYS(2015)<br /><br />CREATE CURSOR junk (test I)<br />FOR ln = 1 TO 10<br />INSERT INTO Junk VALUES (ln)<br />ENDFOR<br /><br />CREATE REPORT &lcReport FROM Junk<br /><br />ThisForm.AddProperty('oListener', null)<br /><br />SET CLASSLIB TO 'C:\Program Files\Microsoft Visual FoxPro<br />9\Ffc\_reportlistener'<br />ThisForm.oListener = CREATEOBJECT('_ReportLIstener')<br />ThisForm.olistener.listenertype = 1<br /><br />THisForm.AddProperty('o2', null)<br />ThisForm.o2 = CREATEOBJECT('ReportListener')<br />ThisForm.oListener.Successor = ThisForm.o2<br /><br />REPORT FORM &lcReport OBJECT ThisForm.olistener</span></span><span style="color:#666666;"><br /></span><br />4. Run the form<br />5. Click the button<br />6. Close the report<br />7. Close the form<br />8. Open the data session window<br />9. Notice an Unknown(#) session.Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-75134875100334822192007-12-04T11:43:00.000-05:002007-12-04T12:04:29.236-05:00Gotcha: Workaround for Data Group bugI've had a few people ask for suggestions on how to work around the ugly data group bug that I previously blogged about. So far, the only work around I have is not generic and has to be applied to EVERY report that uses data groups. I <b>HATE</b> this solution, but it's the only one I have so far.<br /><br />1. Create a report variable for any data you need to show in the Data Group Header. Set the expression to the data field. (rcCustomer)<br /><br />2. Create a report variable to count the number of detail lines in the data group. Set the value to 0, Reset it on the data group, and set the Calculation to Count. (rnCustCount)<br /><br />3. In the Data Group Footer, force the counter to zero after the data group by entering the following in the On Exit Expression: _VFP.SetVar(rnCustCount, 0)<br /><br />4. In the field object in the Data Group header, enter the following in the Print When expression: rnCustCount = 0<br /><br />5. Now copy the field object, but change the reference to the data field to refer to your report variable (rcCustomer). Then change the Print When to rnCustCount > 0. Just stack this on top of the original field object.<br /><br />You now have two objects in the data group header. The original one prints only the first time the data group prints. The second one prints on subsequent pages and uses the report variable instead of the data reference so it will be the right record. An added bonus to this solution is that you can add the word "Continued" in the expression that prints on subsequent pages.Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-10347516009500661382007-11-27T13:40:00.000-05:002007-11-27T13:54:27.525-05:00Gotcha: VFP Reporting BugsI'm really frustrated that I have not received ANY response at all from Microsoft about the recent Data Group bugs I reported. I was already frustrated that they hadn't addressed any of my other report-related bugs .. but these ones are serious and were introduced by SP2. <br /><br />In hopes of putting more pressure on them .. here's a list of all the bugs I have reported through the official channels. You can use the following link to go to the Microsoft Connect page. Near the bottom of the page is a place to enter the ID of the issue. Then you can rate the bug, validate it, and provide any additional comments. Maybe if enough of us complain, they will address it.<br /><br /><a href="https://connect.microsoft.com/VisualStudio/feedback/AdvancedSearch.aspx?Advanced=true&SearchQuery=&FeedbackType=0">Microsoft Connect</a><br /><br />249264 VFP Print When processing wrong parent record<br />291486 VFP Detail Footer Band -- Wrong record<br />292987 VFP Preview - Zoom level not always programmatically changeable<br />293615 Print When logic is evaluated at the wrong time in VFP Reports<br />295113 Shapes stretched across Detail Header and Detail Footer bands whacko<br />288896 Squished Printing<br />286313 VFP SYS(1037) no longer has a PRINTER button in Vista<br />286314 Report Properties dialog locks up<br />286552 Code References - error printing when not in Admin on Vista<br />286958 Drag control from Toolbox to Pageframe and Labels disappear<br />287927 Intellisense on SET gets confused<br />312568 SP2 broke data group headers repeated on subsequent pages<br />312572 Gap with multiple data groups on reportsCathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-69642997105072359242007-11-20T16:16:00.000-05:002007-11-23T14:56:01.989-05:00Gotcha: More on the Data Group BugI've been trying to see if I can come up with a ReportListener that will somehow generically workaround the serious Data Group bug I previously blogged about <a href="http://cathypountney.blogspot.com/2007/11/gotcha-serious-report-bug-with-data.html">(Data Group Bug)</a> In the process, I tried to come up with a really good test report to make sure I'm doing it right. I created a report with 3 data groups so I can be sure my code handles multiple data groups. <br /><br />Well .. let's just say I haven't even gotten to the part of writing code yet. While developing a test report, I came across ANOTHER bug related to data groups. What I'm seeing is a gap on the report after the 3rd data group header prints, but not every time. It only happens for the third data group, when it immediately follows the second data group header. Oh .. and it doesn't happen the first time for the set.<br /><br />Figure 1 shows how the report looks on page 1, which is correct. Figure 2 shows what happens on subsequent pages, which is incorrect.<br /><br /><a href="http://bp2.blogger.com/_sEWO0rxzjkk/R0NRy7gWyuI/AAAAAAAAAEI/DVB-vZfJ1LI/s1600-h/DataGroupGap_Good.jpg"><img style="cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_sEWO0rxzjkk/R0NRy7gWyuI/AAAAAAAAAEI/DVB-vZfJ1LI/s320/DataGroupGap_Good.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5135037935541209826" /></a><br />Figure 1 - The first page - without any gap.<br /><br /><a href="http://bp1.blogger.com/_sEWO0rxzjkk/R0NSHrgWyvI/AAAAAAAAAEQ/RKIM0Q8_eSQ/s1600-h/DataGroupGap_Bad.jpg"><img style="cursor:pointer; cursor:hand;" src="http://bp1.blogger.com/_sEWO0rxzjkk/R0NSHrgWyvI/AAAAAAAAAEQ/RKIM0Q8_eSQ/s320/DataGroupGap_Bad.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5135038292023495410" /></a><br />Figure 2 - Subsequent pages - with a big gap!<br /><br />Obviously, this whole data group issue is getting worse and worse. I'm afraid to keep working on the "workaround" code. Who knows what other bugs I'll uncover! I sure hope Microsoft fixes this! Maybe we should <b>ALL</b> flood them with emails about these report bugs!!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-87314788984940109152007-11-20T06:37:00.000-05:002007-11-23T15:01:40.499-05:00OT: The Challenges of Raising ChildrenRaising children certainly has its challenges, but the last week (especially the last 24 hours) was more than I needed right now in my life!<br /><br />It started last Tuesday when I received a phone call from my 15-yr old son, Kyle, from the Emergency Room. He had wiped out on his gas powered scooter and injured his hand so his father took him to the ER. Kyle called me when leaving the ER and told me that his hand was broken in three places. They put a splint on it and made an appointment for him with an orthopedic specialist for Monday.<br /><br />Accidents happen. Kids get hurt. I can deal with this. But I was not happy when I learned of the circumstances of this injury. Kyle has battery operated lights on the scooter so he can ride after dark. However, on this occasion the batteries were almost dead. He had asked his dad for some new batteries, but his dad didn't have any. Instead of telling Kyle he can't ride in the dark without lights, his father gave him some money and told him to ride to the store to get some. What?!?!?! His father sent him out in the dark on a scooter that goes about 35+ mph. That's ridiculous. And what happened ... There was a folding chair in the middle of the road, Kyle didn't see it, Kyle hit it, and then he went tumbling off the scooter and slid across the pavement for a while. <br /><br />Then on Thursday, my 12-yr old son, Jack, came down with a cold and had to stay home from school for a few days. No big deal .. I can handle this. He went to his father's for the weekend so I made sure I informed his father that he had been sick and throwing up. Apparently his father didn't believe me. On Saturday, his father took him to Buffalo Wild Wings for lunch so they could watch the game. On Sunday, his father took him to the movies. On Sunday night, his father returned Jack to me. Despite the fact that Jack hasn't had an asthma attack in probably a year .. Sunday night, shortly after going to bed, Jack woke up with a severe asthma attack.<br /><br />I tried everything but couldn't stop this attack. So .. off to the emergency room we went. They tried a different medication and were able to stop the attack. Whew .. that ordeal was over. Let's head home and try to get some sleep. Of course, by the time we got home it was 6:15 am and neither of us had gotten any sleep yet. I figured I'd keep Jack home from school again so he can rest up. Me, on the other hand, couldn't exactly do that. Kyle's appointment with the orthopedic doctor was this morning. I figured I might be able to steal 2 hours of sleep before having to get up and get ready ... but that wasn't in the cards either. An hour after I fell asleep, my phone rang 3 times in a 10 minute period. Arrgghh!! I guess I might as well give up and get out of bed. <br /><br />So off to the orthopedic doctor I go to meet Kyle and his father. The doctor told us the hand was actually broken in 4 places, not 3. The doctor told us that he could either put a split on the hand, leaving his thumb and forefinger available for use, or he could put a cast on the hand, which would only leave the thumb available for use. Kyle and his father wanted the split option. I pushed for the cast. Kyle had been told by the ER to NOT remove the split and don't get it wet. Kyle, however, was non-compliant with those instructions. He removed it daily to take a shower and when he reapplied the splint, it was very loose, leaving his fingers (which were broken) loose and able to move. Now let me say at this point that Kyle has been living with his dad, and once again, his dad's poor parenting skills played into this. His father knew Kyle was doing this and didn't enforce the instructions from the ER. So based on all that information, I thought the cast was a better choice, and so did the doctor. So a blue cast was applied and we were sent on our way.<br /><br />Whew, one more ordeal over with. Now to get home, get some lunch, and then try to get some sleep. Wait, I have to go pick up Jack's new prescription first. Then I'll get some sleep. While I was checking out at the counter, my cell phone rang. It was Kyle. He told me he cut his cast off. What?!?!? Are you serious?!??!? Where is your father ... let me speak to him! <br /><br />Apparently, his father didn't take him back to school after the getting the cast. Instead he took him back to his place, and then left to run some errands. When he got back, Kyle had the cast off. Kyle said that it was itching and burning and he couldn't stand it. Here's where I mention that Kyle has Obsessive Compulsive Disorder (OCD) so it doesn't surprise me to know that the cast bugged him. But what did surprise me was that he went to the extreme of cutting it off with scissors, vise grips, and a saw! Oh .. and did I mention that his father had failed to fill his prescription so Kyle had not had is OCD medication in the last few days?<br /><br />So much for my plans to get some sleep. I picked up Kyle and took him back to the orthopedic doctor. This time they put a splint on it .. and lectured Kyle about the importance of leaving it on and NOT removing it. I also had big plans on lecturing his father on that same issue and making sure that he assisted Kyle with wrapping it in plastic and waterproof tape before each shower. By now it's after 5:00 pm and I just want to get home and get some sleep. <br /><br />It's about a 30 minute drive from the doctor's office back home, but we're in 5:00 traffic, and we came to a screeching halt. The main artery from the doctor's office to my house was completely shut down due to a major accident. They were diverting traffic down a side street which couldn't handle the flow of that much traffic. Add to that, there was a semi truck several cars in front of us and he couldn't make the turns through the neighborhood. Arrrgghh! Could this day get any worse?!?!?<br /><br />I phoned Jack who was back at home and asked him to bring up MapQuest on the computer and help me out. Jack did great and gave me directions on how to get out of that mess and get home. Finally, home and exhausted. Jack and I ate a quick dinner and then went to bed ... at 8:30 pm! Thirty minutes later, the asthma attack started again! This time we were able to stop it and finally, we got some sleep. <br /><br />I sure hope today is nice and calm!!!!!!!!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-47599875307104060112007-11-14T20:39:00.000-05:002007-11-23T14:56:44.984-05:00Gotcha: Serious report bug with Data Groups introduced in VFP 9 SP2Here's the situation: You have a report with a data group such as Customer. You checked the "Reprint group header on each page" option to make sure the group header reprints whenever the details for the group overflow to a new page. You put some total information in the group footer band. The report looks somewhat like what is in Figure 1.<br /><br /><a href="http://bp0.blogger.com/_sEWO0rxzjkk/RztvGvXNo5I/AAAAAAAAADo/s5SyyTcoSq0/s1600-h/Group-Good.jpg"><img id="BLOGGER_PHOTO_ID_5132818361902539666" style="DISPLAY: block; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://bp0.blogger.com/_sEWO0rxzjkk/RztvGvXNo5I/AAAAAAAAADo/s5SyyTcoSq0/s320/Group-Good.jpg" border="0" /></a><i>Figure 1: The "Good" report</i><br /><br />Now let's say that the data just so happens to work out so that the last detail record for customer 1 prints at the bottom of the page, thus, the data group footer needs to go to the top of the next page to print.<br /><br />In VFP 7, VFP 8, and VFP 9 SP1 ... you get what's shown in Figure 2. The data group footer for customer 1 prints at the top of the next page, without bothering to reprint the data group header information for customer 1. This is a bug .. but not exactly the end of the world. I could probably live with this anomaly .. if I really had to.<br /><br /><a href="http://bp2.blogger.com/_sEWO0rxzjkk/Rzuf27gWytI/AAAAAAAAAEA/7r6OX3YnQZk/s1600-h/Group-Bad8.jpg"><img id="BLOGGER_PHOTO_ID_5132871966353967826" style="DISPLAY: block; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://bp2.blogger.com/_sEWO0rxzjkk/Rzuf27gWytI/AAAAAAAAAEA/7r6OX3YnQZk/s320/Group-Bad8.jpg" border="0" /></a><i>Figure 2: The "Bad" report in VFP 7, VFP 8, and VFP 9 SP1</i><br /><br />However, in VFP 9 SP2, Microsoft attempted to fix the bug and inadvertently introduced a more severe bug as shown in Figure 3. The data group header prints at the top of the next page BUT it's printing the data from Customer 2, the NEXT record. Then it backs up and the data group footer prints for Customer 1. Then the detail records for Customer 2 begin printing WITHOUT printing the data group header for Customer 2.<br /><br /><a href="http://bp0.blogger.com/_sEWO0rxzjkk/RztvRvXNo6I/AAAAAAAAADw/RKbysM4RLf0/s1600-h/Group-Bad.jpg"><img id="BLOGGER_PHOTO_ID_5132818550881100706" style="DISPLAY: block; MARGIN: 0px 10px 10px 0px; CURSOR: hand; alt: " src="http://bp0.blogger.com/_sEWO0rxzjkk/RztvRvXNo6I/AAAAAAAAADw/RKbysM4RLf0/s320/Group-Bad.jpg" border="0" /></a><i>Figure 3: The "Bad" report in VFP 9 SP2</i><br /><br />As you can see, this is a real mess. Printing the group header with the WRONG customer information is far worse than omitting the group header. This is completely unacceptable in my opinion!! It's completely misleading to print Customer 2 and then show the totals for Customer 1. In fact, as far as I'm concerned, it could cause some serious legal issues for my clients using my reports in some situations.<br /><br />As it stands now, you cannot ever safely print data in the Data Group Header band if it's marked to repeat on subsequent pages. <b>This is a serious bug --- and Microsoft needs to fix this ASAP!!!</b>Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-9095941684733305762007-11-09T22:23:00.000-05:002007-11-09T22:26:10.459-05:00Gotcha: Not all Printers Rotate the Same DirectionThis is the first post in a series I'm calling "Gotcha". This is where I plan to talk about bugs ... er, "features" ... that I've run across or other issues that have caused me grief. Hopefully, by letting you know about them, and some possible work arounds, it will you save you from many future headaches!<br /><br />I’ve been writing reports for years and I recently stumbled across an issue that threw me for a loop. A report that was designed on my machine in Michigan wasn’t working the same in the Tennessee home office. After a lot of hair pulling, the light bulb went off and I realized what the problem was.<br /><br />To print a landscape report, my printer rotates the text counter-clockwise; the printer in the Tennessee office rotates the text clockwise!<br /><br />What? You’ve got to be kidding me. How can this be? I just ASSUMED that all printers rotate the same direction! Isn’t there a “standard” or something that all printer manufacturers follow? Well .. apparently not!<br /><br />So why is this important to you? The answer is … Unprintable Margins.<br /><br />Most printers have unprintable margins that you have to consider when writing reports. Typically, the right and left margins are the same, but the top and bottom margins may be different. Often times, the bottom margin is the largest margin. For example, my printer has .25” on the right and left margins, .07” on the top margin, and a very greedy .48” on the bottom margin. The key here is that these figures apply to a portrait report. When you print a landscape report, these margins are swapped … and the direction of the rotation determines whether the left margin becomes .07” and the right margin becomes .48” or visa-versa.<br /><br />Are you starting to see the problem yet? I designed a landscape report that was tight on the left side and had a half an inch on the right side to accommodate my greedy “bottom” margin. When my coworkers in Tennessee printed the report on their printer, the entire left side was cut off. That’s because their left margin is now the greedy bottom margin. That means they can’t print tight to the left side like I can .. but they can print tight to the right side.<br /><br />So now that you know about this dilemma .. what should you do about it? You can take one of two approaches. The first approach is to design the reports as “Printable Page”, make the landscape width no more than 10.25”, and let the printer decide where to place the text. The other option is to design the report as “Whole Page” and leave a generous .5” margin on both the right and left sides of the landscape report. Personally, I prefer the latter because I like to keep the report centered, but it means I lose a little bit of real estate. Of course, if you ever run across a printer that is even greedier than mine, you’ll have to change your report width accordingly.<br /><br />Knowledge is everything! Hopefully this bit of knowledge will keep you from making the same assumption I did which caused me a lot of grief and aggravation!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-41185092613449441662007-11-08T08:30:00.000-05:002007-11-08T08:32:31.564-05:00Cool Tool: SlickRun by BaydenThis is the first post in a series I'm calling "Cool Tool". As a developer, I spend the majority of my day in front of a computer and I'm all for anything that helps me be more efficient. Whenever I run across a tool or utility that does just that, I'll blog about it and spread the word.<br /><br /><a href="http://www.bayden.com/SlickRun/">SlickRun</a> by Bayden Systems is one such tool. Rick Strahl pointed me to this tool recently and it quickly became one of my favorites. It's a free floating command line utility for Windows and I couldn't live without it now that I have it. It's kinda like batch files on steroids. In fact, now that I have this installed, I have removed most of the icons from my desktop and I use SlickRun to launch almost everything.<br /><br />Here are some examples of what I use it for:<br /><ul><li>I defined "Mail" to launch Outlook and open up my email</li><br /><li>I defined "Music" to launch Yahoo's radio so I can<br />listen to my favorite R&B station.</li><br /><li>I defined "MBS" to launch remote desktop and log into<br />work.</li><br /><li>I defined "Time" to launch Excel and open the spreadsheet I use to track time on projects.</li><br /><li>I defined "UT" to launch Explorer and open up the<br />Universal Thread.</li><br /><li>I defined "Word" to launch Microsoft Word.</li><br /><li>I defined "Newsgroup" to launch my newsgroup reader.</li></ul><br />You basically define a word and then tell it what to launch. And what is even cooler is that you can define one word that launches several other words. For example, I have "morning" defined to open my email, launch the internet, open up remote desktop so I can log into work, launch my time card, and a bunch of other things that I do every morning.<br /><br />It also takes advantage of remembering what I typed last time so when I type "m", it displays "mail" or "music" depending on what I did last time. Often times all I have to type is one letter and it already knows what I want to do. What a huge time saver!!<br /><br />So what's the cost of this great tool? Well .. what's it worth to you? Technically it's free, but donations are certainly appreciated by Bayden. I can tell you that after using this tool for just one day I sent my donation off to Bayden giving them my praise and kudos.<br /><br />I consider this tool a "Must Have" and I'm sure you will too!Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.comtag:blogger.com,1999:blog-5881807458099247013.post-83552898480231043702007-11-05T16:55:00.001-05:002007-11-08T15:32:18.297-05:00Hello WorldI'm throwing my hat into the Blog World. Hopefully I'll be able to come up with enough things to write about on a regular basis.Cathy Pountneyhttp://www.blogger.com/profile/04600819277331440680noreply@blogger.com