Planet FoxPro

September 03, 2010

Alex Feldstein

September 02, 2010

Doug Hennig

More Southwest Fox Links

Kevin Ragsdale has two more excellent blog posts about Southwest Fox sessions he’s been at in the past and what he’s looking forward to seeing this year: Christof Is A Freaking Genius and My Favorite Teacher Is Speaking At Southwest Fox.

The FoxShow has three episodes related to Southwest Fox: FoxShow #65, with Rick Schummer, Tamar Granor, and me discussing this year’s conference, FoxShow #66, in which Toni Feltman discusses her Lean/Agile and Pomodoro sessions, and FoxShow #67, in which Rick Borup discusses his Design Patterns and Ruby and Rails sessions. Andrew apparently has another one coming up featuring Eric Selje.

Southwest Fox starts six weeks from today. Have you registered yet?

by Doug Hennig (noreply@blogger.com) at September 02, 2010 04:14 PM

More Looking at Stonefield Query

George Jensen of CustomerFX has added several more posts about his experience learning Stonefield Query. Check out his articles: part 1, part 2, part 3, part 4, and part 5.

by Doug Hennig (noreply@blogger.com) at September 02, 2010 04:10 PM

www.atoutfox.org

Alex Feldstein

Kevin Ragsdale's FoxPro Blog

My Favorite Teacher Is Speaking At Southwest Fox

Southwest Fox 2005 was the first FoxPro Conference I attended. Though I was a wallflower for most of the conference and kept to myself, I was amazed at the amount of technical knowledge that permeated the air (I spent most of my time at the conference simply absorbing as much of the knowledge as I could).

What I learned in one session that year practically paid for the entire conference, saving me tons of time in my own work. That year, Rick Borup presented Integrating RSS With Visual FoxPro Applications. I had been working on integrating RSS with a couple of apps, and had hit the proverbial brick wall. Everything I tried, failed. Miserably. The harder I worked on it, the worse it got.

In a single 75-minute session, Rick opened the floodgates. My problems were solved that very day as I went back to my hotel room with my laptop that night and started applying what I had learned from Rick to my apps.

Flash forward to 2009. I was (finally) going back to Southwest Fox, and Rick was speaking again, presenting The Show Must Go On: Disaster Recovery and Business Continuity Planning and Quibbles, Quirks, and Quickies. Having promised myself that I would go to at least one of Rick’s presentations anytime I was attending a conference he was speaking at, I chose the Quibbles, Quirks, and Quibbles session.

I didn’t go to that session expecting to learn a whole lot (though I did, especially considering he wrote a 35-page whitepaper for the session). I went because I really appreciate Rick’s style of presenting. He is direct, informative, knowledgeable, and as well-prepared for a session as anyone I’ve ever seen.

There’s never any wasted moments in one of Rick’s sessions.

And that reminds me of my favorite teacher in high school. An Air Force retiree, he taught Algebra, Geometry, and Calculus with an almost surgical precision. Never a wasted moment, always prepared, always something to learn (even when you think you already know everything there is to know).

Rick is speaking again at Southwest Fox. A pre-conference session titled An Introduction to Ruby and Rails, and a regular conference session titled Design Patterns in Visual FoxPro.

There’s no way I’ll miss the Design Patterns session.

This week, Rick was interviewed by Andrew MacNeill on The FoxShow podcast about his sessions for this years conference. As usual, his style was evident: direct, knowledgeable, and prepared.

Rick is one more great reason to attend Southwest Fox this year.

Not registered for the conference yet? Register Now…

by Kevin Ragsdale at September 02, 2010 04:34 AM

September 01, 2010

Beth Massi - Sharing the goodness that is VB

Alex Feldstein

Curly Takes the Stand

<object height="385" width="480"><param name="movie" value="http://www.youtube.com/v/sxAk3B_zS5k?fs=1&amp;hl=en_US"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed allowfullscreen="true" allowscriptaccess="always" height="385" src="http://www.youtube.com/v/sxAk3B_zS5k?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" width="480"></embed></object>

by Alex Feldstein (noreply@blogger.com) at September 01, 2010 01:31 PM

The FoxShow

FoxShow #67: Interview with Southwest Fox speaker, Rick Borup

In this episode, we talk with Rick Borup, one of this year's speakers at Southwest Fox 2010, on design patterns and Ruby on Rails.

The early bird deadline for SW Fox has passed - but that's no excuse not to sign up. Kevin Ragsdale has been serving up some great posts about past sessions he has attended.

by foxshow@gmail.com at September 01, 2010 10:45 AM

Alex Feldstein

Kevin Ragsdale's FoxPro Blog

Christof Is A Freaking Genius

A cool part of the Southwest Fox conference last year was a couple of bonus sessions called Show Us Your App, where several FoxPro developers were given an opportunity to spend 5 to 10 minutes showing off things they’ve worked on.

I showed one of my apps, and focused primarily on how easy it was to add multi-threading capabilities to the app.

Easy, because Christof Wollenhaupt made it easy.

He answered a question in FoxPro Advisor (back when it was an actual magazine) about multi-threading in Visual FoxPro. In his answer, he talked about a DLL he had written which basically allows you to run code in a separate thread. That’s an understatement – one day I’ll write an actual article about my experience and expand on it a bit.

The app I showed uses the IE Web Browser control as it’s primary UI. There are a ton of hyperlinks on certain pages. You click a link and it fires off an HTTP request to collect information and save the collected info into a table.

Since I just love to control how the user uses the app, I displayed a modal window while this request was taking place.

After reading Christof’s piece in Advisor, I decided to use his DLL and make the requests multi-threaded. Now when you click a link, the HTTP request is fired (on a separate thread) and control is immediately returned back to the app. You can click another link while the first one is processing. And another, and another, and another. S-w-e-e-t!

Anyway, during my Show Us Your App bit I mentioned for anyone in the audience that didn’t already know: “Christof is a freaking GENIUS!” (I suspect everyone in the room already knew that). I joked that I was planning to ask my boss to rename the app “Christof Is A Freaking Genius” in honor of the positive effect his work had on my work.

Christof returns to Southwest Fox this year with a pre-conference session titled TLAs put into Practice: Object Oriented Principles in VFP, and a regular conference session titled How the Fox is Different.

He has presented at several Southwest Fox conferences. Last year, he presented Excelporting and Using .NET in FoxPro Applications. Back in 2007, he presented the still-talked-about On the Dark Side of FoxPro.

He is also the creator of Guineu (an alternative runtime library for Microsoft Visual FoxPro 9.0 that runs on any Microsoft .NET compatible platform).

Have a look at his website whitepapers, downloads, and Knowlbits. If you’ve ever wanted to learn more about Visual FoxPro (especially the internals of FoxPro), and you’ve read anything Christof has written, I’m sure you will agree that Christof is a freaking Genius.

He’s also a very friendly and helpful person. Definitely a highlight of attending last year’s conference was the opportunity I had to meet and talk with him.

Poor guy. I followed him around the conference like a puppy dog, making statements and asking questions that I’m sure made me sound like the hack programmer I am. He was friendly, patient, and extremely helpful. I’ll always be grateful for the time I got to spend with him.

I’m looking forward to seeing him again this October.

by Kevin Ragsdale at September 01, 2010 05:10 AM

August 31, 2010

Beth Massi - Sharing the goodness that is VB

Validating Collections of Entities (Sets of Data) in LightSwitch

One of the many challenging things in building n-tier applications is designing a validation system that allows running rules on both the client and the server and sending messages and displaying them back on the client. I’ve built a couple application frameworks in my time and so I know how tricky this can be. I’ve been spending time digging into the validation framework for LightSwitch and I have to say I’m impressed. LightSwitch makes it easy to write business rules in one place and run them in the appropriate tiers. Prem wrote a great article detailing the validation framework that he posted on the LightSwitch Team Blog yesterday that I highly recommend you read first:

Overview of Data Validation in LightSwitch Applications.

Most validation rules you write are rules that you want to run on both the client and the server (middle-tier) and LightSwitch does a great job of handling that for you. For instance when you put a validation rule on an entity property this rule will run first on the client. If there is an error the data must be corrected before it can be saved to the middle-tier. This gives the user an immediate response but also makes the application scale better because you aren’t unnecessarily bothering the middle-tier. Once the validation passes on the client, it is run again on the middle-tier. This is best practice when building middle-tiers - don’t ever assume data coming in is valid.

Validating sets (or collections) of data can get tricky. You usually want to validate the set on the client first but then you have to do it again on the middle-tier, not only because you don’t trust the client, but also because the set of data can change in a multi-user environment. You need to take the change set of data coming in from the client, merge it with the set of data stored in the database, and then proceed with validation. Dealing with change sets and merging yourself can get pretty tricky sometimes. What I didn’t realize at first is that LightSwitch also handles this for you.

Example – Preventing Duplicates

Let’s take an example that I was working on this week. I have the canonical OrderHeader --< OrderDetails >—Product data model. I want a rule that makes sure no duplicate products are chosen across OrderDetail line items on any given order. So if a user enters the same product twice on an order, validation should fail. Here I have an orders screen that lets me edit all the orders for a selected customer. For each order I should not be allowed to enter the same product more than once:

image

Where Do the Rules Go?

You can write rules in xxx_Validate methods for entity properties (fields) and the entity itself. From the Entity Designer select the property name then click the arrow next to the “Write Code” button to drop down the list of available methods. The property methods will display for the selected property. The entity methods are under “General Methods”. In my example if you select the Product property and drop down the list of methods you see two validation methods Product_Validate and OrderDetails_Validate.

image

The Property Methods change as you select an entity property (field) in the designer but the General Methods are always displayed for the entity you are working with. Property _Validate methods run both on the client and then again on the middle-tier. Entity _Validate methods run on the server, these are called DataService validations.

In my order entry scenario I was first tempted to write code in the DataService on the OrderHeader entity and check the collection of OrderDetails there. When I select the OrderHeader entity in the Entity Designer, click the arrow next to the “Write Code” button, and select OrderHeaders_Validate, a method stub is generated for me in the ApplicationDataService class. This is where I was thinking I could validate my set of OrderDetails and return an error if there were duplicates.

Public Class ApplicationDataService

    Private Sub OrderHeaders_Validate(ByVal entity As OrderHeader, ByVal results As EntitySetValidationResultsBuilder)
        Dim isValid = False
        'Write code to validate entity.OrderDetails collection
        '....
        If Not isValid Then
            results.AddPropertyError("There are duplicated products on the order")
        End If
    End Sub
End Class

However I quickly realized that this wouldn’t work because the OrderHeader entity would need to be changed for this validation to fire. If a user is editing a current order’s line items (OrderDetails) then only the validation for the OrderDetail would fire, not OrderHeader. Another issue with putting my rule in the ApplicationDataService class is the user would have to click save before the rule would fire and we’d have an unnecessary round-trip to the middle-tier. We want to be able to check this set for problems on the client first. Another issue is if I found an error then only a general validation message on the order would be presented to the user. They would have to stare at the screen to figure out the problem.

I think the reason why I went this route in the first place is because I was thinking I needed to merge the change set coming from the client with the set of data in the database and then validate that. It turns out that LightSwitch handles this for you. When you are validating a set of data (entity collection) on the client, you are validating what is on the user’s screen. When the validation runs on the server you are validating the merged set of data. NICE!

(Note that you can still access the change set via the DataWorkspace object but we’ll dive into that in a future post. )

The Right Way to Write this Rule

Since LightSwitch is doing all the heavy-lifting for me this rule gets a whole lot easier to implement. Since we’re checking duplicate products on each OrderDetail we need to put the code in the Product_Validate method of the OrderDetail entity (see screenshot above). Now we can write a simple LINQ query to check for duplicates.

Public Class OrderDetail

    Private Sub Product_Validate(ByVal results As EntityValidationResultsBuilder)

        If Me.Product IsNot Nothing Then

            'Look at all the OrderDetails that: 
            '   1) have a product specified (detail.Product IsNot Nothing)
            '   2) have the same product ID as this entity (detail.Product.Id = Me.Product.Id)
            '   3) is not this entity (detail IsNot Me)
            Dim dupes = From detail In Me.OrderHeader.OrderDetails
                          Where detail.Product IsNot Nothing AndAlso
                                detail.Product.Id = Me.Product.Id AndAlso
                                detail IsNot Me

            'If Count is greater than zero then we found a duplicate
            If dupes.Count > 0 Then
                results.AddPropertyError(Me.Product.ProductName + " is a duplicate product")
            End If
         End If
    End Sub
End Class

This validation will fire for every line item we add or update on the order. It will first fire on the client and Me.OrderHeader.OrderDetails will be the collection of line items being displayed on the screen. If this rule passes validation on the client then it will fire on the middle-tier and the Me.OrderHeader.OrderDetails will be the collection of line items that were sent from the client merged with the data on the server. This means that if another user has modified the line items on the order we can still validate this set of data properly. Also notice when we specify the error message, it is attached to the Product property on the OrderDetail entity so when the user clicks the message in the validation summary at the top of the screen, the proper row in the grid is highlighted for them.

image

Stay tuned for more How Do I videos on writing business rules.

UPDATE: Here's a video I did on writing business rules: How Do I: Write business rules for validation and calculated fields in a LightSwitch Application?

Enjoy!

by Beth Massi at August 31, 2010 11:43 PM

Alex Feldstein

Doug Hennig

Quote of the Conference

Kevin once again has a great blog post, this time about Tamar’s Southwest Fox session on business objects. His “kick me in the gut” moment was when Tamar pointed out that by separating user interface from business logic, you free your application from the limitations of the UI, making redesign and testing much easier (I’m paraphrasing and extrapolating from what Kevin said).

Like Kevin, I’m looking forward to Tamar’s Collections: Managing Information the Object-Oriented Way session at this year’s conference.

by Doug Hennig (noreply@blogger.com) at August 31, 2010 03:12 PM

Alex Feldstein

Kevin Ragsdale's FoxPro Blog

And Now You Can Run The App From The Command Window

What the heck does the title of this post mean?

If you were at Tamar Granor’s Getting Your Head Around Business Objects session at last year’s Southwest Fox conference, you’d know exactly what it means.

If you weren’t at last years conference, Tamar is another reason why you should go this year.

Tamar’s session focused on business objects. She started with explanations of what business objects are, and delved a bit into the history of business objects in Visual FoxPro (think frameworks).

She showed how she used business objects in a real-world application, and followed that with a Sudoku game, built with Visual FoxPro.

We got a brief glance at the UI for the Sudoku game, then Tamar walked us through the classes (object hierarchy) she had built. One of the most interesting parts for me was how she had used collection classes for business objects.

I really wanted to learn more about that, and I must be one of the luckiest people in the world: she’s presenting Collections: Managing Information the Object-Oriented Way at this years conference.

Most of the session was dedicated to building the “engine” for the application, using business objects. After she was done showing the classes, object hierarchy and how she linked the classes together, she said something that really kicked me in the gut – a real “A-HA!” moment for me:

“And now, you can run the app from the Command Window.”

If they gave awards for best quote of the conference, that quote would have won hands-down.

And she was right. The entire game could have been played from the Visual FoxPro Command Window, with no UI. The rest of the session was spent showing us how to connect the business objects (the engine) with the user interface.

I was stunned at the amount I had learned in 75-minutes. Even better, Tamar wrote a detailed 42-page whitepaper and provided the source code for the Sudoku game which she used as the example for the session.

Going to a session by Tamar is like going to a class lecture that you want  to attend. She is professional, informative and entertaining all at once. Which to me is a great combination of skills, and exactly what I look for when I’m selecting sessions to attend.

Early-bird registration ends September 1st. If you haven’t registered for this years conference, stop reading my drivel and go. register. now.

by Kevin Ragsdale at August 31, 2010 04:31 AM

Alex Feldstein

That Mitchell and Webb Look - Football

<object height="385" width="640"><param name="movie" value="http://www.youtube.com/v/xN1WN0YMWZU?fs=1&amp;hl=en_US"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed allowfullscreen="true" allowscriptaccess="always" height="385" src="http://www.youtube.com/v/xN1WN0YMWZU?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" width="640"></embed></object>

by Alex Feldstein (noreply@blogger.com) at August 31, 2010 01:34 AM

August 30, 2010

Alex Feldstein

August 29, 2010

Alex Feldstein

Photo of the Day


The Cloisters at the Spanish Monastery - Miami

From their site:
The Monastery of St. Bernard de Clairvaux was built in Sacramenia, in the Province of Segovia, Spain, during the period 1133-1144.

In 1925 William Randolph Hearst purchased the Cloisters to move it to his estate in California. The structures were dismantled stone by stone, packed in some 11,000 wooden crates, numbered for identification and shipped to the United States.

Soon after the shipment arrived, Hearst’s financial problems forced most of his collection to be sold at auction. The stones remained in a warehouse in Brooklyn, New York, for 26 years. One year after Hearst’s death in 1952, they were purchased by Messrs. W. Edgemon and R. Moss for use as a tourist attraction. It took 19 months to put the Monastery back together in Miami, where it stands today.

by Alex Feldstein (noreply@blogger.com) at August 29, 2010 09:25 AM

LessThanDot - All Blogs - Author(s): 218

Interesting T-SQL problems

by Naomi

With this blog post I am hoping to start a new series of blogs devoted to the interesting T-SQL problems I encounter in forums during the week.

The idea of this blog series came to me on Wednesday night when I thought I solved a complex problem...

First Problem

The first problem, I'd like to discuss, is found in this MSDN thread:

Given this table

SalesDateTimeSalesAmount
2010-08-10 00:05:1258.22
2010-08-10 00:08:2221.10
2010-08-10 00:09:388.45
2010-08-10 00:18:049.52
2010-08-10 00:19:5645.20
2010-08-10 11:35:1547.12
2010-08-10 11:36:1288.55
2010-08-10 11:40:3145.12

find the Average Sale amount for the 15 minutes time interval.

The first idea, that comes to mind, of how to solve this problem, is to use integer math in T-SQL. In T-SQL, unlike other languages, when you divide one integer by another integer, you get an integer in return.

So, if we divide datepart(minute,SalesDateTime) / 15 we will organize the data into the 15 minutes intervals.

Now, my first idea was to use datepart function to get year, month, day, hour portion of the date and then construct the date based on these parts using concatenation and string functions. However, upon thinking I realized we can use convert function to grab first portion of the datetime field (up to hours), then add Group * 15 to get the minute part and then convert back to datetime. While I was writing this solution and testing it, Tom Cooper came up with the simpler idea based on the datediff function and fixed date.

I list both of the solutions below:

Code: tsql
DECLARE @Sales TABLE (SalesDateTime DATETIME,     SalesAmount DECIMAL(10,2))
INSERT INTO @Sales
SELECT
 
'2010-08-10 00:05:12',   58.22
UNION all SELECT
'2010-08-10 00:08:22',   21.10
UNION all SELECT
'2010-08-10 00:09:38',   8.45
 
 UNION all SELECT
 
'2010-08-10 00:18:04',   9.52
UNION all SELECT
'2010-08-10 00:19:56',   45.20
 
 UNION all SELECT
 
'2010-08-10 11:35:15',   47.12
UNION all SELECT
'2010-08-10 11:36:12',   88.55
UNION all SELECT
'2010-08-10 11:40:31',   45.12
UNION all SELECT
'2010-08-10 11:52:31', 23.45
 
-- Naomi's query
 
;with cte AS (SELECT MIN(SalesDateTime) AS MinDate,
MAX(SalesDateTime) AS MaxDate,
CONVERT(VARCHAR(14),SalesDateTime, 120) AS StartDate, DATEPART(MINUTE, SalesDateTime) /15 AS GroupID,
AVG(SalesAmount) AS AvgAmount
FROM @Sales
GROUP BY CONVERT(VARCHAR(14),SalesDateTime, 120),
DATEPART(MINUTE, SalesDateTime) /15)
 
SELECT DATEADD(MINUTE, 15*GroupID, CONVERT(DATETIME,StartDate+'00')) AS [START DATE],
DATEADD(MINUTE, 15*(GroupID+1), CONVERT(DATETIME,StartDate+'00')) AS [END DATE],
CAST(AvgAmount AS DECIMAL(12,2)) AS [Average Amount],
MinDate AS [MIN DATE], MaxDate AS [MAX DATE]
FROM cte
 
-- Tom Cooper's query
;With cte AS
(SELECT DATEADD(MINUTE, 15 * (DATEDIFF(MINUTE, '20000101', SalesDateTime) / 15), '20000101') AS SalesDateTime, SalesAmount
FROM @Sales)
SELECT SalesDateTime, CAST(AVG(SalesAmount) AS DECIMAL(12,2)) AS AvegSalesAmount
FROM cte
GROUP BY SalesDateTime;



Second Problem

The second problem is really a gem and it is presented in How can I find overlapped ranges? thread

Name Chromosome Start End
N1 chr3 17443613 17443685
N2 chr3 17443521 17443685
N3 chr2 162180459 162180499
N343 chr2 131865573 131865687
N34 chr16 34623393 34623610
N2456 chr3 17443512 17443685
N43243 chr3 17443608 17443685

The whole table is about 31,000 records (includes 22 chromosomes + X, Y chromosomes).

The problem is to find the overlapped regions (or ranges) and these overlapped records have to be on the same Chromosome of this table.

-------------
I saw this problem at ~11pm on Wednesday night, thought I solved it and that's when the idea of this blog came to my mind.

The next day, however, based on Hunchback's (Alejandro Messa) comment I realized, that my "solution" worked only for a single overlapping range for the same chromosome. If we have multiple overlapping ranges, that solution will not work. I spent ~ an hour trying to fix my idea for multiple overlapping ranges, but gave up at the end, as I had work to do. So, I will show two ingenious solutions of this problem presented in that thread by (Peso) Peter Larsson.

First let's create the test table with 100K records:

Code: tsql
CREATE TABLE [dbo].[Chromosomes](
    [Name] [VARCHAR](10) NOT NULL,
    [Chromosome] [VARCHAR](10) NOT NULL,
    [iStart] [INT] NOT NULL,
    [iEnd] [INT] NOT NULL
)
Go
CREATE NONCLUSTERED INDEX [IX_Chromosomes] ON [dbo].[Chromosomes]
(
    [Chromosome] ASC,
    [iStart] ASC,
    [iEnd] ASC
)
INCLUDE ( [Name])
INSERT INTO Chromosomes
SELECT    'N' + CAST(ABS(CHECKSUM(NEWID())) % 5000 AS VARCHAR(12)) AS Name,
    'chr' + CAST(ABS(CHECKSUM(NEWID())) % 22 AS VARCHAR(12)) AS Chromosome,
    iStart,
    iStart + ABS(CHECKSUM(NEWID())) % 10000 AS iEnd
FROM    (
        SELECT    TOP(100000)
            ABS(CHECKSUM(NEWID())) % 200000000 AS iStart
        FROM    Tally
    ) AS d
   
SELECT * FROM Chromosomes

The first solution uses cursor and takes ~27 sec. to execute:

Code: tsql
-- Cursor based idea
SET NOCOUNT ON
DECLARE @TimeStart DATETIME = GETDATE()
CREATE TABLE    #Work
        (
            Chromosome VARCHAR(10) NOT NULL,
            FromNum INT NOT NULL,
            ToNum INT NOT NULL,
            NAMES VARCHAR(MAX) NOT NULL,
            Items INT NOT NULL
        )
 
CREATE CLUSTERED INDEX IX_Chromosome ON #Work (Chromosome, FromNum)
 
DECLARE    curWork CURSOR READ_ONLY FOR    SELECT        Chromosome,
                            iStart,
                            iEnd,
                            Name
                    FROM        dbo.Chromosomes
                    ORDER BY    Chromosome,
                            iStart
 
DECLARE    @FromNum INT,
    @ToNum INT,
    @Chromosome VARCHAR(10),
    @Name VARCHAR(10)
 
OPEN    curWork
 
FETCH    NEXT
FROM    curWork
INTO    @Chromosome,
    @FromNum,
    @ToNum,
    @Name
 
WHILE @@FETCH_STATUS = 0
    BEGIN
        UPDATE    #Work
        SET    FromNum = CASE WHEN FromNum < @FromNum THEN FromNum ELSE @FromNum END,
            ToNum = CASE WHEN ToNum < @ToNum THEN @ToNum ELSE ToNum END,
            NAMES = CASE WHEN NAMES LIKE '%, ' + @Name + ', %' THEN NAMES ELSE NAMES + ', ' + @Name END,
            Items = Items + 1
        WHERE    Chromosome = @Chromosome
            AND FromNum <= @ToNum
            AND ToNum >= @FromNum
 
        IF @@ROWCOUNT = 0
            INSERT    #Work
                (
                    Chromosome,
                    FromNum,
                    ToNum,
                    NAMES,
                    Items
                )
            VALUES    (
                    @Chromosome,
                    @FromNum,
                    @ToNum,
                    @Name,
                    1
                )
 
        FETCH    NEXT
        FROM    curWork
        INTO    @Chromosome,
            @FromNum,
            @ToNum,
            @Name
    END
 
CLOSE        curWork
DEALLOCATE    curWork
 
SELECT        Chromosome,
        FromNum,
        ToNum,
        NAMES,
        Items
FROM        #Work
--WHERE        Items > 1    -- Uncomment this line to get only the overlapping ranges
ORDER BY    FromNum
 
DROP TABLE #Work
PRINT 'Time elapsed (sec): ' + CONVERT(VARCHAR(30),DATEDIFF(SECOND, @TimeStart, GETDATE()))

Set based solution based on the quirky update idea - it takes ~5 second to execute:

Code: tsql
SET STATISTICS TIME OFF
SET NOCOUNT ON
DECLARE @TimeStart DATETIME = GETDATE()
SELECT  Name,
    Chromosome,
    iStart,
    iEnd,
    0 AS Grp
INTO    #Temp
FROM    dbo.Chromosomes
 
DECLARE @Grp INT = 0,
    @Chromosome VARCHAR(10) = '',
    @END INT = 0
 
;WITH cteUpdate(Chromosome, iStart, iEnd, Grp)
AS (
    SELECT      TOP(2147483647)
            Chromosome,
            iStart,
            iEnd,
            Grp
    FROM        #Temp
    ORDER BY    Chromosome,
            iStart
)
-- Quirky update - updating variable and field at the same time
UPDATE  cteUpdate
SET @Grp = Grp =    CASE
                WHEN Chromosome <> @Chromosome THEN @Grp + 1
                WHEN @END < iStart THEN @Grp + 1
                ELSE @Grp
            END,
    @ENDCASE
            WHEN Chromosome <> @Chromosome THEN iEnd
            WHEN iEnd < @END THEN @END
            ELSE iEnd
        END,
    @Chromosome = Chromosome
 
SELECT      Chromosome,
        MIN(iStart) AS FromNum,
        MAX(iEnd) AS ToNum,
        CAST(MIN(Name) AS VARCHAR(MAX)) AS NAMES,
        COUNT(*) AS Items,
        Grp
INTO        #Stage
FROM        #Temp
GROUP BY    Chromosome,
        Grp
 
UPDATE      s
SET     s.NAMES += f.NAMES
FROM        #Stage AS s
CROSS APPLY (
            SELECT DISTINCT ', ' + x.Name
            FROM        #Temp AS x
            WHERE       x.Grp = s.Grp
                    AND x.Name > s.NAMES
            FOR XML     PATH('')
        ) AS f(NAMES)
WHERE       s.Items > 1
 
SELECT      Chromosome,
        FromNum,
        ToNum,
        NAMES,
        Items
FROM        #Stage
ORDER BY    Chromosome,
        FromNum
 
DROP TABLE  #Temp,
        #Stage
       
PRINT 'Time elapsed (sec): ' + CONVERT(VARCHAR(30),DATEDIFF(SECOND, @TimeStart, GETDATE()))


Third problem

The third problem is simple enough, but yet quite interesting. It is presented in the following Vertical Result Set thread

Transpose table of any structure vertically (in other words, each column becomes a row) and show just a few typical data for every column.

First problem is to convert the data into the same format. I chose nvarchar(max), but it may not be 100% working solution if there are columns with exotic data type that can not be converted to nvarchax(max). In this case we may want to use sql_variant as the type instead.

Here is the solution I used based on AdventureWorks.Person.Address table:

Code: tsql
DECLARE @SQL NVARCHAR(MAX)
 
SELECT @SQL = COALESCE(@SQL + '
FROM AdventureWorks.Person.Address
UNION ALL
','') + 'SELECT convert(nvarchar(max),' + QUOTENAME(column_name) + ') as Column_Value, ' +
QUOTENAME(Column_Name,'''') + ' as Column_Name'
 FROM AdventureWorks.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Address' and TABLE_SCHEMA = 'Person'
--print @cols
 
 
SET @SQL =' ;with cte as (' + @SQL + '
FROM AdventureWorks.Person.Address)
-- get 10 records per each column
select * from (select *,
row_number() over (partition by Column_Name order by Column_Value) as row
from cte) X
where Row <=10'
ORDER BY ROW, Column_Name
--print @SQL
 
EXECUTE(@SQL)

And here is Hunchback (Alejandro Messa) solution using SQL Server 2008 specific syntax:

Code: tsql
SELECT
    C.*
FROM
    (
 SELECT TOP (3)
     AddressID,
     AddressLine1,
     AddressLine2,
     City,
     StateProvinceID,
     PostalCode
 FROM
     Person.Address
 ORDER BY
  ModifiedDate
 ) AS T
 CROSS APPLY
 (
 VALUES
  (AddressID, 'AddressID', CAST(AddressID AS SQL_VARIANT)),
  (AddressID, 'AddressLine1', CAST(AddressLine1 AS SQL_VARIANT)),
  (AddressID, 'AddressLine2', CAST(AddressLine2 AS SQL_VARIANT)),
  (AddressID, 'City', CAST(City AS SQL_VARIANT)),
  (AddressID, 'StateProvinceID', CAST(StateProvinceID AS SQL_VARIANT)),
  (AddressID, 'PostalCode', CAST(PostalCode AS SQL_VARIANT))
 ) AS C(rowident, cn, cv)
ORDER BY
 rowident,
 cn;
GO

Hope you find these problems interesting as well and see you in a week...




*** Remember, if you have a SQL related question, try our Microsoft SQL Server Programming forum or our Microsoft SQL Server Admin forum

by Naomi at August 29, 2010 05:28 AM

Alex Feldstein

August 28, 2010

The Problem Solver

Converting a C# workflow into XAML

A interesting question that came up last week was how to convert workflows defined in C# to XAML.

A co worker of one of the attendees of the Essential Windows Workflow Foundation 4 course had been experiencing a lot of problems with the workflow designer and decided to create their workflows in C# instead of using the designer to generate XAML. While these workflows run just fine you do lose the visual aspect of the designer, one of the benefits of workflow in the first place.

Fortunately it isn’t hard to save workflow objects, however they have been authored, into their XAML representation using the XamlServices.

Take the following workflow defined in C#.

var workflow = new Sequence();
workflow.Activities.Add(new WriteLine() { Text = "Hello workflow." });
workflow.Activities.Add(new Persist());
workflow.Activities.Add(new If()
{
    Condition = new VisualBasicValue<bool>("System.DateTime.Now.Hour < 12"),
    Then = new WriteLine() { Text = "Good morning" },
    Else = new WriteLine() { Text = "Good afternoon" }
});
workflow.Activities.Add(new WriteLine()
{
    Text = new VisualBasicValue<string>("\"The current time is: \" & System.DateTime.Now.ToLongTimeString()")
});

This will run just fine as is but if I want to convert this into XAML all I need is a single line of code:

XamlServices.Save(@"..\..\demo.xaml", workflow);

And when it runs I get a nice XAML file with the graphical representation of the original C# workflow.

image

And now I can continue enhancing the XAML version and run that instead.

 

Enjoy!

www.TheProblemSolver.nl
Wiki.WindowsWorkflowFoundation.eu

by Maurice at August 28, 2010 02:01 PM

Andrew MacNeill - AKSEL Solutions

Another Reason to visit SW Fox: Software, Software, Software

Doug recently linked to Kevin Ragsdale's post about why people should attend Southwest Fox. If you've been listening to the FoxShow recently, we've been interviewing speakers and there are more interviews to come in the next few weeks.

AKSEL is also proud to announce that we are offering two subscriptions to MSDN Visual Studio 2010 Ultimate for attendees. If you don't already have MSDN, this is effectively your way of getting every piece of business/developer related software from Microsoft.

Rick, Doug and Tamar will be drawing for the lucky attendee at this year's conference - so you have to be there to win it.

As a note, if you DO already have MSDN, Pay it forward and be sure to throw the subscription back into the hat for others who may not be getting it to get the chance to work with the latest development tools from Microsoft. Note: this subscription also includes great designer tools like Expression with Sketchflow which I love for prototyping applications.


by Andrew MacNeill (noreply@blogger.com) at August 28, 2010 10:27 AM

Alex Feldstein

Shedding Some Light

Southwest Fox 2010 Early-bird Deadline

There is still time before September 1st to get in on the Early-Bird Registration for Southwest Fox 2010! The Early-Bird discount saves you $50 over our regular conference registration.

This year’s conference, held October 14-17, includes 15 speakers, 26 different sessions in the main conference, 4 pre-conference topics, and a free one-day VFP to Silverlight post-conference workshop. Plus, if you’re a member of a registered VFP user group, when you attend Southwest Fox, your user group receives $25.

In case you haven’t heard, we made a change in venue back in late July. The conference moved to a new location: SanTan Elegante Conference & Reception Center/Legado Hotel. Room rates are “run of the house” at $119 a night. You can find all the details at http://swfox.net/hotel.aspx. The room block for the conference is held through September 13th; after that room availability and pricing is determined by the hotel.

We are planning to add a “Show Us Your App” bonus session based on the success of the session the last couple of years.

Got suggestions? info@swfox.net Got questions? info@swfox.net Got registrations? register@swfox.net, or you can call the Geek Gatherings’ World Headquarters at 586.254.2530.

Read about the registration process and get the registration application here: http://www.swfox.net/register.aspx

Follow the news about the conference on our blog: http://swfox.net/blog/index.htm

Use our brochure to convince your boss (or spouse or SO) to let you go: http://www.swfox.net/brochure.pdf

Only 48 days until we meet in Gilbert. Hope to see you there.

by Rick Schummer at August 28, 2010 12:04 AM

August 27, 2010

Doug Hennig

Southwest Fox 2010 Early-Bird Deadline Next Week

There is still time before September 1st to get in on the Early-Bird Registration for Southwest Fox 2010! The Early-Bird discount saves you $50 over our regular conference registration.

This year's conference, held October 14-17, includes 15 speakers, 26 different sessions in the main conference, 4 pre-conference topics, and a free one-day VFP to Silverlight post-conference workshop. Plus, if you're a member of a registered VFP user group, when you attend Southwest Fox, your user group receives $25.

In case you haven’t heard, we made a change in venue back in late July. The conference moved to a new location: SanTan Elegante Conference & Reception Center/Legado Hotel. Room rates are "run of the house" at $119 a night. You can find all the details at http://swfox.net/hotel.aspx. The room block for the conference is held through September 13th; after that room availability and pricing is determined by the hotel.

We are planning to add a "Show Us Your App" bonus session based on the success of the session the last couple of years.

Got suggestions? info@swfox.net Got questions? info@swfox.net Got registrations? register@swfox.net, or you can call the Geek Gatherings' World Headquarters at 586.254.2530.

Read about the registration process and get the registration application here: http://www.swfox.net/register.aspx

Follow the news about the conference on our blog: http://swfox.net/blog/index.htm

Use our brochure to convince your boss (or spouse or SO) to let you go: http://www.swfox.net/brochure.pdf

Only 48 days until we meet in Gilbert. Hope to see you there.

by Doug Hennig (noreply@blogger.com) at August 27, 2010 09:51 PM

F1 Technologies Blog

VFE: Changing how system settings are stored.

Every so often I am still amazed at how awesome the VFE Framework really is. I hear a lot about YAGNI these days (you ain't going to need it) and how unnecessary features can be very wasteful. The following example illustrates how careful thought and design may save hours and hours of future development time.

I have a client who is having a lot of trouble with Users who run his app on Windows Vista and Windows 7. The problem is with access to the registry and all of the setting that VFE stores there. So, he asked me to modify the app to store these settings in a table. Now, we are not going to discuss whether a VFP table was the right approach or not. That would need to be a separate discussion. I began looking at the app and what I would need to do in order to change all of the system setting calls to read from and write to a table. I couldn't believe how easy it was. The following are the three steps. I had this feature completed far faster than I ever thought I would.

Step 1: Subclass cSystemSetting (or iSystemSetting) into a new class. I chose to put mine in the application layer but it could go in the iLayer just as easily. Get and Set are the key methods.

Step 2: Modify your new settings class to create the table, read from it and write to it. I also added code to delete and recreate the table/index if there were corruption problems. Since they are just settings, the client was fine with blowing everything away if necessary.

Step 3: Plug in the new system setting class through your application level factory table using the description of System Setting Manager.

That is all there was to it. I love this framework!

by Toni M. Feltman (noreply@blogger.com) at August 27, 2010 09:05 PM

Calvin Hsia's WebLog

Use Perfmon to analyze your managed memory

You can learn all sorts of information about your application using Perfmon. You can also inspect various aspects of managed memory.<o:p></o:p>

<o:p> </o:p>

How much time is spent in garbage collection? When managed code runs, memory management is done for you, but at the cost of freezing your application while GC is doing its thing.<o:p></o:p>

<o:p> </o:p>

The sample code below creates many instances of a class called Big, which can hold a reference to another of the same class. If the instances of Big are linked together, they can’t be GC’d, til the end of the loop so the memory footprint is very different without the links.<o:p></o:p>

<o:p> </o:p>

Start VS 2010, File->New->Project->C#->Windows->WpfApplication, <o:p></o:p>

Open the MainWindow.xaml.cs file, replace with the code below<o:p></o:p>

Hit F5 to run.<o:p></o:p>

<o:p> </o:p>

Start Perfmon: Windows Key+R  Perfmon<o:p></o:p>

Click on Performance Monitor in tree on left.<o:p></o:p>

By default, % Processor time is displayed in a graph<o:p></o:p>

Click the big red X to delete it.<o:p></o:p>

Click the big green + to bring up the Add Counters dialog to add some things to monitor<o:p></o:p>

<o:p> </o:p>

Click on “.NET CLR Memory” in the first listbox.<o:p></o:p>

<o:p> </o:p>

For Instances of selected object:, choose “WpfApplciation1.vshost” and then click “Add”, “OK”<o:p></o:p>

<o:p> </o:p>

These are the performance counters graphed on Windows 7:<o:p></o:p>

<o:p> </o:p>

# Bytes in all Heaps<o:p></o:p>

# GC Handles<o:p></o:p>

# Gen 0 Collections<o:p></o:p>

# Gen 1 Collections<o:p></o:p>

# Gen 2 Collections<o:p></o:p>

# Induced GC<o:p></o:p>

# of Pinned Objects<o:p></o:p>

# of Sink Blocks in use<o:p></o:p>

# Total committed Bytes<o:p></o:p>

# Total reserved Bytes<o:p></o:p>

% Time in GC<o:p></o:p>

Allocated Bytes/sec<o:p></o:p>

Finalization Survivors<o:p></o:p>

Gen 0 heap size<o:p></o:p>

Gen 0 Promoted Bytes/Sec<o:p></o:p>

Gen 1 heap size<o:p></o:p>

Gen 1 Promoted Bytes/Sec<o:p></o:p>

Gen 2 heap size<o:p></o:p>

Large Object Heap size<o:p></o:p>

Process ID<o:p></o:p>

Promoted Finalization-Memory from Gen 0<o:p></o:p>

Promoted Memory from Gen 0<o:p></o:p>

Promoted Memory from Gen 1<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

You can select various ones individually by clicking on the associated Show checkbox.<o:p></o:p>

Try looking at these closely:<o:p></o:p>

Gen 0 heap size<o:p></o:p>

Gen 1 heap size<o:p></o:p>

Gen 2 heap size<o:p></o:p>

% Time in GC<o:p></o:p>

<o:p> </o:p>

MultiSelect a few and right click ->Scale selected counters if you like. <o:p></o:p>

<o:p> </o:p>

At one point (change the size of the Big array to 10000), I got 70% time in garbage collection! (The values in the Textboxes are not scaled, and it showed 47.)<o:p></o:p>

<o:p> </o:p>

Try commenting out the backlink line (ptrPrev assignment) or vary the size of Big and see the effect.<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

<o:p> </o:p>

See also<o:p></o:p>

Examine .Net Memory Leaks<o:p></o:p>

Heartbeat: Garbage collection in VFP and .NET are similar<o:p></o:p>

Use temporary projects in Visual Studio<o:p></o:p>

PerfMon Sample: Demonstrates How to Monitor System Performance Using Performance Counters<o:p></o:p>

Managed code using unmanaged memory: HeapCreate, Peek and Poke<o:p></o:p>

<o:p> </o:p>

<C# Code><o:p></o:p>

using System;<o:p></o:p>

using System.Collections.Generic;<o:p></o:p>

using System.Linq;<o:p></o:p>

using System.Text;<o:p></o:p>

using System.Windows;<o:p></o:p>

using System.Windows.Controls;<o:p></o:p>

using System.Windows.Data;<o:p></o:p>

using System.Windows.Documents;<o:p></o:p>

using System.Windows.Input;<o:p></o:p>

using System.Windows.Media;<o:p></o:p>

using System.Windows.Media.Imaging;<o:p></o:p>

using System.Windows.Navigation;<o:p></o:p>

using System.Windows.Shapes;<o:p></o:p>

<o:p> </o:p>

namespace WpfApplication1<o:p></o:p>

{<o:p></o:p>

    /// <summary><o:p></o:p>

    /// Interaction logic for MainWindow.xaml<o:p></o:p>

    /// </summary><o:p></o:p>

    public partial class MainWindow : Window<o:p></o:p>

    {<o:p></o:p>

        public MainWindow()<o:p></o:p>

        {<o:p></o:p>

            InitializeComponent();<o:p></o:p>

            for (int i = 0; i < 1000; i++)<o:p></o:p>

            {<o:p></o:p>

                System.Diagnostics.Debug.WriteLine(i.ToString());<o:p></o:p>

                var root = new Big();<o:p></o:p>

                var ptrCurrent = root;<o:p></o:p>

                for (int j = 0; j < 30000; j++)<o:p></o:p>

                {<o:p></o:p>

                    var big = new Big();<o:p></o:p>

                    big.ptrPrev = ptrCurrent; // make them all link together so they can't be collected<o:p></o:p>

                    ptrCurrent = big;<o:p></o:p>

                    System.Threading.Thread.Sleep(1);<o:p></o:p>

                }<o:p></o:p>

            }<o:p></o:p>

        }<o:p></o:p>

        public class Big<o:p></o:p>

        {<o:p></o:p>

            public int[] data;<o:p></o:p>

            public Big ptrPrev; // backlink<o:p></o:p>

            public Big()<o:p></o:p>

            {<o:p></o:p>

                data = new int[1000];<o:p></o:p>

            }<o:p></o:p>

        }<o:p></o:p>

    }<o:p></o:p>

}<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

 </C# Code><o:p></o:p>

<o:p> </o:p>

<VB Code><o:p></o:p>

Class MainWindow<o:p></o:p>

    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded<o:p></o:p>

        For i = 0 To 1000<o:p></o:p>

            System.Diagnostics.Debug.WriteLine(i.ToString())<o:p></o:p>

            Dim root = New Big()<o:p></o:p>

            Dim ptrCurrent = root<o:p></o:p>

            For j = 0 To 30000<o:p></o:p>

                Dim big = New Big()<o:p></o:p>

                big.ptrPrev = ptrCurrent ' make them all link together so they can't be collected<o:p></o:p>

                ptrCurrent = big<o:p></o:p>

                System.Threading.Thread.Sleep(1)<o:p></o:p>

            Next<o:p></o:p>

        Next<o:p></o:p>

<o:p> </o:p>

    End Sub<o:p></o:p>

<o:p> </o:p>

    Class Big<o:p></o:p>

        Dim data(1000) As Integer<o:p></o:p>

        Public ptrPrev As Big<o:p></o:p>

    End Class<o:p></o:p>

End Class<o:p></o:p>

<o:p> </o:p>

</VB Code><o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

<o:p> </o:p>

Thanks, Calvin<o:p></o:p>

http://blogs.msdn.com/calvin_hsia<o:p></o:p>

<o:p> </o:p>

by Calvin_Hsia at August 27, 2010 07:52 PM

Alex Feldstein

August 26, 2010

Alex Feldstein

Photo of the Day


Star Island with Miami skyline and the Port of Miami in the background.

by Alex Feldstein (noreply@blogger.com) at August 26, 2010 10:35 AM

VFP IMAGING

FoxyPreviewer 1.80

CodePlex FoxyPreviewer downloads page

Export your reports to Images, RTF, PDF, HTML, XLS, CSV or TXT super easy! Send them by email! Enhance the look of your previews!

 

*** v1.80 - UPDATED 2010-08-26*** 

  • New exporting options: TXT, CSV and XL5
  • New CDO email options
  • New Properties / improvements
  • by Mauricio Braga
     - lSaveAsTXT    - logical, allows saving to TXT, CSV or XL5
     - cOutputPath   - character, determines the output path the user wants the reports to be saved
  • by Jacques Parent
     - lAutoSendMail - logical, allows to directly send e-mail with no preview display
     - lDirectPrint  - logical, directly send to printer with no preview display
     - lSilent       - logical, makes FoxyPreviewer completely silent for report errors
     - cError        - character, the errors occurred
     - cEmailCC, cEmailBCC, cEmailReplyTo - character, for the CDO email type
     - In CDO email type: Included the auto detection of HTML body or TEXT body (if text begins with <HTML>)
     - In CDO email type: Included the auto detection for the anonymous connection to the e-mail server (No user and password)
     
    Some remarks:
     
    1 - Save as TXT option, in the dialog, you may choose between TXT, CSV and XL5
    TXT will generate the old ASCII file report
    CSV will convert the main alias to a CSV delimited with ";"
    XL5 will do the same as above, converting the main alias to the XLS / XL5 type
     
    2 - I still did not update the email form to allow the new propertiesthat Jacques enabled for email. I hope to do that for the next release.

*** v1.77 - UPDATED 2010-07-26*** 

  • Updated the Localizations table with the French, Persian, Greek - Thanks to Michel Levy, Ali Hosein Zadeh, Nick Porfirys.
  • Improvement: Included CodePage in LOCS table to automatically create PDFS according to the local language - by Nick Porfirys.
  • Improvement in class initialization.
  • New "LocalLanguage" field, storing the local name used for the language.
  • Fix: Settings form translation was failing in some situations.
  • Fix: ExcelListener was generating wrong numeric values if SET("POINT")=","

*** v1.73 - UPDATED 2010-07-27*** 

  • Updated the Localizations table with the Spanish, Czech, Turkish and Arabic translations, Juan Antonio Santana and Rick Castro, Martin Krivka, Soykan Ozcelik and Dany Eid
  • Fix: FoxyPreviewerCaller.Prg adapted to work with the new settings possibilities. 

*** v1.72 - UPDATED 2010-07-26*** 

  • updated the Localizations table with the German and Indonesian translations, thanks to Stefan Wuebbe and Samir H.
  • Fix: the toolbar will be disabled when the Settings form will be called
  • Fix: in the language assignment at initialization

*** v1.71 - UPDATED 2010-07-24*** 

  • Updated the Localizations table in order to update the new settings form
  • New property: nButtonSize - Numeric, 1 = Small - 16x16 pixels (default), 2 = Big - 32x32 pixels

*** v1.70 - UPDATED 2010-07-22*** 

  • Fix: ExcelListener was raising an error when the report used the _PAGETOTAL variable
  • Fix: When the Miniatures form was minimized the miniaturesdid not show
  • Renamed property: Old name: PDFnPageMode; New name: nPDFPageMode
  • New Property: "lShowPrinters" - Logical, determines if the available printers combo will be shown
  • New Property: "nShowToolbar"  - Numeric, determines the visibility of the toolbar
     && 1 = Visible (default), 2 = Invisible, 3 = Use resource
  • New Property: "lShowSetup" - Logical, determines if the FoxyPreviewer setup button will be shown
  • New Property: "nMaxMiniatureDisplay" - Numeric, the number of miniature to display in the miniature form
  • New Property: "nShowToolBar" - numeric, determines if the toolbar will be visible or not at startup && 1 = Visible (default), 2 = Invisible, 3 = Use resource
  • New Property: "lShowSetup" - logical, determines if the setup button will be shown
  • New Property: "lShowPrinters" - logical, determines if the available printers combo will be shown
  • Other New Properties: for Email sending using CDOSYS
     nEmailMode          && 1 = MAPI, 2 = CDOSYS, 3 = Custom procedure
     cSMTPServer  
     nSMTPPort    
     lSMTPUseSSL  
     cSMTPUserName
     cSMTPPassword 
     cEmailTo     
     cEmailSubject
     cEmailBody   
     cEmailFrom
  • New dialog forms:
           "Settings", allow user to define most of the available settings for the current and next session of Foxypreviewer
           "Send Email" Form allowing user to pass email information
  • When the user chooses to save as "XLS", it will allow saving using the XML extension, because the output file will be able to be opened by other tools, such as OpenOffice.
  • Tweaks in the sample distribution project, to adapt it to the new changes.
  • Fix: RTF and PDF Listeners now work with basic rounded shapes
  • Fix: FoxyPreviewerCaller.Prg cleanup improved, now PAPERSIZE and ORIENTATION are kept when the EXPRE cleanup is done (Thnaks to Nick Porfirys)
  • Several improvements on the settings form
  • New downloads page at CodePlex

*** v1.53 - UPDATED 2010-07-08*** 

  • Several new tweaks in translations
  • GoToPage form translations activated
  • Removed the exibition of the FRX nme if using the cTitle property
  • Changed all buttons to use the property SpecialEffect = 2, in order to keep the same appearance of the original report toolbar
  • Updated samples, using translated versions
  • Special thanks to Manuel B and Jacques Parent for their big contribution for this release, testing, providing suggestions and fixes. Very much apreciated !

*** v1.52 - UPDATED 2010-07-08*** 

  • New property: cLanguage, to determine the language for the dialogs and tooltips. Available at this moment: ENGLISH (default), PORTUGUES, ESPANIOL, GERMAN, TURKISH, ITALIANO, CZECH, PERSIAN, GREEK, FRENCH, POLISH, INDONESIAN
       Notice that I removed all the translations from FoxyPreviewer.H
       There I only kept information about the default language to be selected. This is to be used if you use FoxyPreviewer to set the global variable "_REPORTPREVIEW"
  • Several tweaks in FoxyPreviewerCaller
  • Fix in Report title, was showing "TMP_"

*** v1.49 - UPDATED 2010-06-30*** 

  • Improvement: Included the "PrinterPreferences" button to the Default Preview Toolbar, the one used without calling FoxyPreviewer.
  • New translations, Polish and Indonesian, thanks to Kazimierz Pszenny and Samir H.
  • Improvement: Allows using bigger icons, such as 32x32
  • Replaced original icons due to some doubts about licensing, now using icons from www.pixel-mixer.com, that are free to use for commercial use.
  • New definitions in FoxyPreviewer.H allow you to change the name of the image buttons to be used.

*** v1.45 - UPDATED 2010-06-19*** 

  • Fix: Property "lPrinted" now returns the correct value if user selected the "Printer Prompt" dialog (Printer preferences button), thanks to Martin Krivka
  • Updated Greek translation
  • Improvement: Now the preview title bar displays: "Page - PageTotal" when user selectes 1Page mode i.e.: "Page 5 - 1500" or: "Pages from %FP% to %LP%" when user selectes 2Page or 4Page mode i.e.: "Pages from 5 to 6" or "Pages from 5 to 8", thanks to Nick Porfyris

*** v1.43 - UPDATED 2010-06-16*** 

  • Fix: Page# will appear translated in the Preview Form titlebar

*** v1.42 - UPDATED 2010-06-15*** 

  • Fix: PDFListener was not rendering some strings when Dynamic properties were incorrectly set, reported by Anil Kamat 
  • Fix: AddReport() new tweaks, thanks to Carlos Morandin
  • New property: PDFnPageMode, numeric, Default = 0, 0 = Normal view, 1 = Show the outlines pane, 2 = Show the thumbnails pane, 3 = Full Screen
  • Improvement: Included support for labels (LBX) in FoxyPreviewerCaller.prg, thanks to Nick Porfyris

*** v1.41 - UPDATED 2010-06-14*** 

  • Fix: ExcelListener now renders "&" characters correctly
  • Improvement: New parameter allowed in method "AddReport(tcFRX, tcClauses, tcAlias)", allowing specifying the alias to be selected when the desired report will be executed.
  • Tweak: Miniatures form will not show the nvigtion buttons when the quantity of pges will not exceed the existing quantity of pages. (by Jacques Parent)

*** v1.40 - UPDATED 2010-06-13*** 

  • Fix: "SET TALK ON" bug in SP2 reporting bypassed. Now PDF and HTML outputs will not dirty the console http://cathypountney.blogspot.com/2009/04/set-talk-appears-to-be-on-when-running.html
  • Fix: "AddReport()" bug, was not allowing chained reports, thanks to Craig Boyd
  • New property - "lUseListener", when .F., REPORTBEHAVIOR will be set to 80 (old way), to generate good printings on dot-matrix printers.
  • Improvement: new internal function to detect if the output printer is Dot-Matrix type; 
    if positive, the report will be sent to the printer using REPORTBEHAVIOR 80
  • Improvement: Lots of cool tweaks from Jacques Parent, specially in the miniatures form, allowing to have all available pages miniatures
  • Improvement: French translation from Jacques Parent
  • New property "cEmailPRG"
       Character, receives the name of a PRG that will fire your custom email.
       In this PRG, you need to receive one parameter, ec tcFile, that is the temporary output file that you'll send by email.   
       A complete sample, "MYSENDMAIL.PRG" is available, showing you how you can send your emails
       Uses a CDOSYS class, courtesy of Sergey Berezniker
       http://www.berezniker.com/content/pages/visual-foxpro/send-email-msn-email-account
       http://www.berezniker.com/content/pages/visual-foxpro/cdo-2000-class-sending-emails

*** v1.31 - UPDATED 2010-04-28*** 

*** v1.30 - UPDATED 2010-04-26*** 

  • Fix: "Save As" menu working in Top-Level forms (Thanks to Tushar)

*** v1.26a - UPDATED 2010-04-01***

  • Fix: PDF Listener accepts GIFs
  • Fix: "Save As" menu working in Top-Level forms
  • Fix: PDF Listener will use Gdi+ to convert a not supported image
  • Enhancement: New MAPI function to send emails
  • Enhancement: The property "cDestFile" can be filled manually, in order to generate output files without previewing
  • Fix: Excel output files are saved in the desired folder

*** v1.25 - UPDATED 2010-03-28***

  • Fix: HTML output now works correctly in EXE.
  • Fix: Turned off SetConsole during PDF generation
  • The "Priting Preferences" button now activates the "PRINTER PROMPT" dialog, that enables users to change the current printer, and all available settings. This provides the maximum customization.
  • Included a new file - FoxyPreviewer.H, that contains the localized constants for the strings.
  • Included the CZECH, PERSIAN and GREEK localized strings in FoxyPreviewer.H. Now we have translations for 9 languages available.
  • New Property : "cCodePage" && Default = "CP1252", CodePage, to be used by PDF Listener
  • New Property : "lQuietMode" && Default = .T., determines the QuietMode property for the listeners used
  • New Property : "lPDFasImage" && Default = .F., the PDF document will be an image document
  • Enhancement: PDFx received some tweaks in order to generate smaller files when repeated images are used in reports. Thanks to Luis Navas
  • Updated FoxyPreviewerCaller.Prg to accept the new properties

*** v1.23 - UPDATED 2010-02-28***

  • New tweaks for Top-Level forms - now the parent form will have its "Closable" property set as false during report preview, and reset on preview release (Thanks to Stefan Wuebbe)
  • Fixes in RTF and PDF Listeners, now images with Isometric settings correctly rendered. (Thanks to Andrew Nickless)
  • Fix in PDF rendering for GIF conversion (Thanks to Kevin)

*** v1.22 - UPDATED 2010-02-23***

  • Improvement: New property: nDockType (see description below)
  • Improvement: New PRG, FoxyPreviewerCaller.Prg, to be included in the EXE. It allows using embedded reports in the EXE, using the APP file. TO be better documented soon. See sample in downloads file.

*** v1.21 - UPDATED 2010-02-22 ***

  • Fix: Enlarged label size for RTF output
  • Fix: Included file "FrxPreview.H" in distribution (needed by ExcelListener)
  • Tweak: Removed progress dialogs in spanish. All listeners have all progress dialogs disabled
  • New properties:
    • Output types allowed in the "Save as.." button from the toolbar
    lSaveAsImage
    lSaveAsHTML
    lSaveAsRTF
    lSaveAsXLS
    lSaveAsPDF
    • Defining the previewform.WindowState
nWindowState && 0 = Normal, 2 = Maximized

*** v1.20 - UPDATED 2010-02-21 ***

  • Improvement: PDFListener now draws backgrounds for fields and labels
  • Improvement: RTFListener now draws backgrounds for fields and labels
  • New feature: Basic Excel output available (Using ExcelListener by Alejandro Sosa, first implemented by Edwin Duran)
    • Important - Excel listener, differently from PDF and RTF listeners is being provided as is. I will not support new features or improvements to this listener. My goal is to offer another output possibility, but I really can't add fetures, or important fixes. As it is open source, feel free to add your improvements and fixes. I'll be happy to update the version distributed with FoxyPreviewer if you send it to me. Using version 1.02 from UT, having disabled the automatic file opening after generation, and also removed the CTL32 Progressbar

*** v1.18 - UPDATED 2010-02-18***

  • Fix: RTFListener now works correctly when _PageTotal is used
  • Fix: RTFListener now works with CMYK JPGs, TIFFs and PNGs
  • Fix: PDFxListener now works with all kinds of images
  • Fix: PDFxListener now draws transparent shapes 

*** v1.16 - UPDATED 2010-02-13***

  • Fix: TopForm property error in initialization
  • Fix: Now the _ReportPreview cache will be always cleared to avoid errors during toolbar rebuilding
  • Many tweaks in the _ReportPreview factory

*** v1.15 - UPDATED 2010-02-10***

  • Fix: Context menu now works normally in Top-Level forms.
  • MAJOR CHANGE: Now distributing a separate APP file that is a library that contains ALL the required files for FoxyPreviewer to run properly, including: LibHaru.dll, _GdiPlus.vcx, _ReportListener.vcx, FoxyPreviewer classes, PDFx, RTFListener, and all support images. This post will be updated soon, with more detailed information about these changes.

*** v1.11 - UPDATED 2010-02-09***

  • Fix: Context menu now works normally when the toolbar is invisible.

*** v1.10 - UPDATED 2010-02-07***

  • Fixed forced preview close (Vivek Deodhar)
  • Included new "Printer preferences" button in toolbar and context menu (using codes from Barbara Peisch)
  • Fixed "lPrintVisible" property error (Zen Tes)

*** UPDATED 2010-02-04***

  • Included translation to Italian (thanks to Fabio Lenzarini)
  • Fix: Printing in a network printer was not working correctly
  • Fix: method RunReport, missing "This" in some lines of code (Benny Thomas)
  • Fixed RTFListener colors initialization, thanks to Hector Urrutia
  • Removed the "NORESET" clause on merged reports. Users should add it by themselves in case they need
  • Renamed the ReportListener helper classes
    (PDFx became PR_PDFX and FRX_RTF became PR_RTFListener),
    in order to avoid people messing with the original versions from the authors.
    The versions distributed with FoxyPreviewer are tweaked ones

*** UPDATED 2010-02-03***

  • Included translation to Turkish (thanks to Soykan Ozcelik)
  • Fix: RTF Listener was omitting 1st page when Range clause was used
  • Fix: Property "lSaved" was not becoming 'True' when an image file was saved

*** UPDATED 2010-02-02***

  • Tweaked German translation
  • Fixed GotoPage dialog not working when toolbar was not visible
  • Fixed Default printer in Combobox

*** UPDATED 2010-02-01***

  • Included translation to German (Thanks to Tom Knauf)
  • Fixed toolbar regeneration when user closed the toolbar using the "X" button
  • Now compatible with VFP9 1st release and SP1 (SP2 strongly recommended)

 

FoxyPreviewer is my report generating class, that brings some cool and useful functions, as you can see in the pictures below.

 

FEATURES

 

1 - Preview Toolbar

The original toolbar was modified, with some new button images, and new buttons too !

 

2 - Printers ComboBox

The printers combobox will show you all the available printers (local and in the network), and allows you to change the deviate the output to any printer that you want.

3 - Copies spinner

Determine on the fly the quantity of copies that you want to print!

 

4 - Miniatures button

View miniatures of all pages of the current report. Clicking on any miniature will jump the output page to the selected one.

 

 

5 - Save As.

A new button that calls a context menu that allows you to save the current report as:

  • Image Files - EMF, PNG, JPG, BMP, GIF, TIFF
  • HTML
  • PDF
  • RTF, a MS-Word compatible format
  • XLS, a MS-Excel simplified worksheet new!

6 - Context menu

The report context menu was updated as well, receiving all the new buttons and pictures. For the case of the "Save as." button, a submenu brings all the output possibilities.

 

 

 

7 - Changing the Printer Preferences. New !

Now you can access the Printer Preferences dialog to change the default printer settings of the selected printer. Works on all Windows versions!

When you click on this button:

 

You'll get a printer dialog from your current printer. For my case I got:

 

 

 

8 - Translating ALL report windows, dialogs, tooltips and captions.

Have you noticed that the context menu above is in spanish ? You can determine in what language your report will be working with. Currently FoxyPreviewer is available in English, Portuguese and Spanish. It's up to you to decide in what language the dialogs will be shown.

 

Go to page dialog in spanish

 

 

USAGE

 

To test FoxyPreviewer, download this file, unzip it, and run the file TESTPREVIEWER.PRG. Please make sure to start VFP from this file, by doubleclicking on this file from Explorer, to make sure that the default path is automatically set, and all the needed files will be found.

 

To use it with your own reports is super simple, with just three lines of code:

LOCAL loReport AS "PreviewHelper" OF "FoxyPreviewer.prg"
loReport = CREATEOBJECT("PreviewHelper")
loReport.AddReport(_Samples + "\Solution\Reports\colors.frx", "RANGE 1,1 NODIALOG") && FRX File, Clauses
loReport.RunReport()

 

The main file is FOXYPREVIEWER.PRG that contains the PreviewHelper class that is the class that you need to instantiate to have the new toolbar options. It uses the ReportListener's ExtensionHandler class to make all the changes in the original toolbar. This file also brings the classes from Colin Nicholls, that generate the miniatures sheet.

For the RTF output, kudos go to Vladimir Zhuravlev's RTFListener class. Impressive how he managed to make it! No need of any external library, RTF Listener converts your report into an RTF file, that can be perfectly opened and viewed in MS-Word ! I applied some fixes in the original version, now allowing all the text output to be shown correctly, enabled colors for texts, backgrounds and shapes, and also images stored in general fields. Another small tweak was added to allow merging reports.

The PDF files are generated using Luis Navas' amazing PDFx class. It uses an external library, Haru Free PDF Library 2.0.8, from Takeshi Kanno. Super light weight, no need to install a ghostscript printer, no dependancies to generate your PDFs! More info at Luis Navas' blog: http://weblogs.foxite.com/luisnavas/archive/2008/10/06/7025.aspx. The original version from Luis also received some few tweaks, to allow merging reports, and also eliminating the need to use the GdiPlusX library from VFPX. Now it used the _GdiPlus.vcx FFC class, that is already stored in the Report*.App files, that are already available in all VFP9 sources. I decided doing that because the GDI+ usage was really very very simple, and the FFC classes were enough for that purpose. Hey ! I keep recommending to everybody to use GdiPlusX !!!

 

CUSTOMIZING

Of course, you may choose what features will be available in the report preview toolbar. There are some few and obvious properties that you may set in order to fit your needs. Below are the methods and properties available:

 

Methods - all obligatory

  • AddReport(tcFRXFile, tcClauses, tcAlias) 
    That's the place where you determine what report and which clauses will be used 
    tcFRXFile - character, the FRX to be run 
    tcClauses - character, the report clauses 
    eg.: .AddReport(_Samples + "\Solution\Reports\wrapping.frx", "NODIALOG FOR title = 'S' RANGE 3,3")

 

  • RunReport() 
    Runs the chosen report, and shows the preview window and FoxyPreviewer toolbar

 

Properties - all optional

  • cTitle - character, the preview window title
  • lSendToEmail - logical, determines if the "send to email" button will be shown (not available yet)
  • lSaveToFile - logical, determines if the "saveto file" button will be shown
  • lShowCopies - logical, shows the copies spinner
  • lShowMiniatures - logical, shows the miniatures page
  • nCopies - numeric, the default quantity of copies to be printed
  • lPrintVisible - logical, shows the print button in the toolbar
  • cDefaultListener - character or object, the name or object from the default listener to be used; the default one is "FXLISTENER"
  • nCanvasCount - numeric, the initial nr of pages rendered on the preview form. Valid values are 1 (default), 2, or 4.
  • nZoomLevel - numeric, the initial zoom level of the preview window. Possible values are:
    1-10%, 2-25%, 3-50%, 4-75%, 5-100% default, 6-150% ;
    7-200%, 8-300%, 9-500%, 10-whole page
  • lPrinterPref - logical, shows the "Change printer preferences" button in the toolbar new!
  • lSaveAsImage - logical, includes the "save as Image" option in menu new!
  • lSaveAsHTML - logical, includes the "save as HTML" option in menu new!
  • lSaveAsRTF - logical, includes the "save as RTF" option in menu new!
  • lSaveAsXLS - logical, includes the "save as XLS" option in menu new!
  • lSaveAsPDF - logical, includes the "save as PDF" option in menu new!
  • nWindowState - numeric, defines the previewform.WindowState 0 = Normal, 2 = Maximized new!
  • nDockType - logical or numeric (0-4). If False, the dock will follow the resource file used. Or numeric, to force the toolbar docking. new!
  • nMaxMiniatureDisplay - numeric, the quantity of reports to be shown in the miniatures form.
  • cFormIcon - character, the file name of the icon to be used in the preview and other helper forms
  • lEmailAuto - logical, Automatically generates the report output file
  • cEmailType - character, the file type to be used in Emails (PDF, RTF, HTML or XLS)
  • lEmailed - logical, returns .T. (true) if an email has been sent
  • cEmailPRG - character, the name of a PRG that will fire your custom email. In this PRG, you need to receive one parameter, tcFIle, that is the temporary output file that you'll send by email. A complete sample, "MYSENDMAIL.PRG" is available, showing you how you can send your emails. To use it, you need to set the value of this property, for instance: .cEmilPrg = "MySendMail.Prg"
  • cCodePage - character, the codepage to be used by the PDF listener && Default = "CP1252"
  • lUseListener - logical, determines if ReportListeners will be used during printing. The report previsualization will always use listeners. There are some situations or incompatibilities between some printers and report listeners so you may try setting this property to .F. to get an "old way" printing. So, when .F., REPORTBEHAVIOR will be set to 80. Useful for dot-matrix printers.
  • lQuietMode - logical, determines the QuietMode property for the listeners used && Default = .T.
  • lPDFasImage - logical, the PDF document will generated as an image document && Default = .F.
  • cDestFile - character, determines the filename of the output file to be generated when "RunReport()" is called. If you set this propertym the report will not be previewed
  • PDFnPageMode - integer, determines the Page mode for the PDF document. &&  Default = 0, 0 = Normal view, 1 = Show the outlines pane, 2 = Show the thumbnails pane, 3 = Full Screen

 

AUTOMATING WITH INTELLISENSE

I've also created a small PRG that updates the FOXCODE table in order to add an Intellisense script to use it. Please run the file INSTALLFOXCODE.PRG to update the Intellisense.

To test it, open any empty PRG or Method, and just type:

FOXYPREVIEW and a complete script with all available options will be shown. Obviously, you may delete or comment all the properties that you don't want to use.

 

CHANGING ALL PREVIEWS

Another cool feature is that you can also set the Global _REPORTPREVIEW variable to "FoxyPreviewer.prg", and all your reports, even those that will not create the Helper Object will have that look. Unfortunately, I could not add all the options from the toolbar to them, because it is impossible to retrieve the "FOR" clauses after a report is run.

Just type the following in your command window:

  _ReportPreview = "FoxyPreviewer.prg" 
  REPORT FORM _Samples + "Solution\Reports\Colors.frx" PREVIEW

Notice that some functions are not available in this option, but some cool ones remain, like the changes picture buttons, translations, the Miniatures is still avalable, and the save to file can only save the report in image file.

 

TRANSLATING TO NON ENGLISH LANGUAGES

 

To enable it, just open the FoxyPreviewer.H, and you'll find the language definitions. Comment the line that defines the default language to English, and uncomment the one that sets it to the desired language. It's very simple to add another language, just open FoxyPreviewer.prg and translate the #DEFINE's constants to your native language. I'll be very happy to add other localized languages to the main download ! Please, if you do translate it to another language, send to me your translation !

To enable the spanish language, for instance just leave the desired language uncommented

* #DEFINE PR_ENGLISH
* #DEFINE PR_PORTUGUES
* #DEFINE PR_GERMAN
* #DEFINE PR_ITALIANO
* #DEFINE PR_TURKISH
* #DEFINE PR_CZECH
* #DEFINE PR_GREEK
* #DEFINE PR_PERSIAN
* #DEFINE PR_FRENCH

#DEFINE PR_ESPANIOL

 

 

DISTRIBUTION

FoxyPreviewer consists of a set of separate utilities, that were adapted to work together.
These files include classes, prgs, images, dlls and header files.

In order to simplify the distribution and to avoid adding many individual files to your project, all the related files have been compiled into a single APP file - FoxyPreviewer.App

The usage is simple:
Store the file FoxyPreviewer.App in the same folder that you have your EXE or the Report*.App files.
Add to your main project just one file: FOXYPREVIEWERCALLER.PRG

The usage is EXACTLY the same as if you were using the PRG - the only difference is that instead of starting the FoxyPreviewer class directly, you'll access the Helper class that I created that you'll include in your EXE.
This was necessary in order to allow FoxyPreviewer to access the FRX files from your EXE. Being an external library, FoxyPreviewer.App can't access directly the FRX that are in your EXE. That's the reason that I'm asking you to include the helper file, FoxyPreviewerCaller.Prg in your EXE. That way, the helper class is inside your EXE, and it can access your FRX, and pass them to the Previewer class.

Behind the scenes, this helper class stores a copy of the FRX classes from your EXE in a TEMP file, that is used by FoxyPreviewer. This helper class does the needed cleanups, deleting the temporary files. All the properties available in the main class are available in the helper as well, so you'll use it the same way:

SET PROCEDURE TO FoxyPreviewerCaller.prg ADDITIVE 

LOCAL loReport as "FoxyPreviewerCaller" OF "FoxyPreviewerCaller.Prg"
loReport = CREATEOBJECT("FoxyPreviewerCaller")

WITH loReport as ReportHelper
	.AddReport("Sample.frx", "RANGE 1,1 NODIALOG")
	.RunReport()
	
	DO CASE
	CASE .lPrinted	
		MESSAGEBOX("Report was printed !",64, "Report status")
	CASE .lSaved
		MESSAGEBOX("Report was saved as file:" + CHR(13) + .cDestFile,;
			64, ;
			"Report status")
		=Thisform.OpenFile(.cDestFile)
	OTHERWISE
		MESSAGEBOX("Report Preview was closed without saving or printing",48, "Report status")
	ENDCASE
ENDWITH

 

The APP distributed is using the English language translation by default.
If you want to change it to your own language, we have already 9 options available: English, portuguese, spanish, turkish, german and italian. Just edit the file Foxypreviewer.H, uncomment your desired language in the 1st lines, and recompile it, generating your localized FoxyPreviewer.App file that you'll distribute.


The other option is to include all classes, VCX/VCT, images, the header files (*.H), and the file FoxyPreviewer.Prg in your Project, and compile. That's all. This brings the advantage of including FoxyPReviewer in your executable:

  • pr_ExcelListener.vcx
  • pr_PDFx.vcx
  • pr_RtfListener.vcx
  • GdiPlus.vcx
  • _ReportListener.vcx
  • _FRXCursor.vcx

 

  • FoxyPreviewer.prg

 

  • FoxPro_Reporting.H
  • FoxyPreviewer.H
  • FrxPreview.H
  • GdiPlus.H
  • GdiPlus_locs.H
  • HPDF_consts.H
  • ReportListeners.H
  • ReportListeners_Locs.H
  • WinCrypt.H
  • _FrxCursor.H
  • _Reports.H

 

  • LibHPDF.dll

 

  • pr_IMAGES.bmp
  • pr_Bottom.bmp
  • pr_Close.bmp
  • pr_Close2.bmp
  • pr_Excel.bmp
  • pr_GoToPage.bmp
  • pr_Html.bmp
  • pr_Img.bmp
  • pr_Locate.bmp
  • pr_Mail.bmp
  • pr_Next.bmp
  • pr_Pdf.bmp
  • pr_Previous.bmp
  • pr_Print.bmp
  • pr_PrintPref.bmp
  • pr_Save.bmp
  • pr_Top.bmp
  • pr_Word.bmp
  • WWrite.ico

 

FUTURE IMPROVEMENTS

 

  • Another missing point is the "SendToEmail" option. This involves an HTML editor form, and a CDOSYS email class, lots of images, etc. I hope to add it to FoxyPreviewer soon. I already have this working in my own framework, but I still have to disconnect some objects in order to add them to this project, and to allow some other customizations, like allowing you to choose another email component to send your emails. The HTML editor was adapted from the original from Frederick Steczicky and Tracy Pearson, published in www.atoutfox.com .

 

SPECIAL THANKS / AUTHORS

As you could see, FoxyPreviewer is the result of some researches, and the use of some amazing tools provided as open source and free from other foxers. The VFP community is amazing !!!

 

Lisa Slater Nicholls - for the great job that she made with the reporting system of VFP9 SP2. And more than that, for her great blog, the excellent and well documented articles.

 

Colin Nicholls - He's the author of the Miniatures form; for his many great articles too regarding the new reporting system, specially for the article Exploring and Extending Report Previewing in VFP9. I took the miniatures preview form classes from there.

 

Luis Navas - He's the author of the PDF Listener. A terrific job, great code. More info about PDFx can be obtained in his blog: PDFx Update Support for some SP2 Features. This brings a new, lightweight and very reliable option for us to export our reports to PDFs. Thanks a lot for your support and help with this project !

 

Vladimir Zhuravlev - He's the author of the RTF Listener together with Dmitriy Petrov and Valeriy Liftshits with help of Vadim Pirozhkov. It was published in the Foxite downloads section - http://www.foxite.com/downloads/default.aspx?id=166. Another impressive and courageous work. Thanks very much !

Leandro Walfrans for testing and Luis Maria Guayan, for his continuous support and for the spanish translations. Tom Knauf, for the german translation.

Takeshi Kanno, the author of the HARU PDF library, and all his collaborators, for making PDFx come true with HARU library. More information about this great project: http://libharu.org/wiki/Main_Page

Barbara Peisch, for the codes to open the "Printer Preferences" dialog window, posted in the Foxite forums: http://www.foxite.com/archives/0000158197.htm

Edwin Duran, for the samples using ExcelListener, created by Alejandro Sosa

Sergey Berezniker, for the email CDO class used in the samples, and for some codes used to get printer information.

 

 

DISCLAIMER

This software ("FoxyPreviewer") and the distributed classes are provided "as is'.

You may use the Software for any commercial or noncommercial purpose, including distributing derivative works.

In return, we simply require that you agree:

1. Not to remove any copyright or other notices from the Software, or from the distributed classes, created by other authors.

2. That the Software comes "as is", with no warranties. None whatsoever. This means no express, implied or statutory warranty, including without limitation, warranties of merchantability or fitness for a particular purpose or any warranty of title or non-infringement.

3. That no contributor to the Software will be liable for any of those types of damages known as indirect, special, consequential, or incidental related to the Software or this license, to the maximum extent the law permits, no matter what legal theory it's based on. Also, you must pass this limitation of liability on whenever you distribute the Software or derivative works.

 

DOWNLOAD

CodePlex FoxyPreviewer downloads page

Hope you enjoy !

by cesarchalom at August 26, 2010 02:10 AM

August 25, 2010

Kevin McNeish [C# and .NET]

Why do I get a TypeLoadException when moving my project to .NET 4?

There have been some security changes in the .NET 4.0 Framework, so when moving a project to .NET 4.0 you may get the following exception: TypeLoadException - Derived Types must either match the security accessibility of the base type or be less accessible...(read more)

by KevinMcNeish at August 25, 2010 06:38 PM

Ted Roche's weblog

Notes from ManchLUG’s Launch Meeting

Twenty-seven people attended the first meeting of the Manchester Linux User Group, held on August 24, 2010 at Wings Your Way, Elm Street, in Manchester, NH. Congrats to organizers Kenta Koga and Chip Marshall for taking the initiative to start a group, finding a location and publicizing the meeting!

The meeting was primarily a meet-up, more focused on finding out if people would come out than running a training session. Kenta and Chip made a few announcements at the beginning of the meeting, including mentioning the GNHLUG calendar at http://gnhlug.org (on a Mac!), Leslie Poston’s efforts to bring together a lot of local tech and social media calendars on Google, activities happening at Float Left Labs and their Archimedes Space in Manchester, Jellies at Studio99 in Nashua.

Conversations were pretty local at that point, with a lot of people in a small space with good food and beers and apparently lots to say. What a joyous noise!

Thanks to Kenta and Chip for organizing the event, to Wings Your Way in Manchester for providing the space and to all who attended!

by tedroche at August 25, 2010 06:01 PM

Alex Feldstein

August 24, 2010

Alex Feldstein

Beth Massi - Sharing the goodness that is VB

Visual Studio LightSwitch How Do I Videos

I’ve done my fair share of How Do I videos over the years, particularly on Visual Basic and related technologies. And even though I really don’t like hearing the sound of my own voice (who is that? ;)) I do love teaching. I also love doing How Do I videos for LightSwitch because the tool really lends itself well to short 5-10 minute videos. I’ll be working on more of them this week and will release them weekly. For now, enjoy the first 5 that we released yesterday on the LightSwitch Developer Center.

These videos are meant to be watched in order because each one builds on the last one. If you are familiar with the old Windows Forms Over Data series I did a few years ago, the application will be familiar to you because we build out the same tables and fields for a simple order management system in this series. It’s amazing how much farther along we get in this series building the application with LightSwitch instead.

In the next few videos I’m going to tackle Custom Validation, Master-Detail forms, Lookup Tables, and some more advanced Queries.

Enjoy!

by Beth Massi at August 24, 2010 04:53 PM

Alex Feldstein

August 23, 2010

Beth Massi - Sharing the goodness that is VB

LightSwitch Public Beta 1 Now Available!

We’ve just released the public Beta 1 of Visual Studio LightSwitch! Yay! Check out Jason Zander’s post LightSwitch Beta1 Now Available, Building Your First App.

To get started, visit the LightSwitch Developer Center:

image

Here you can access the download, watch step-by-step “How Do I” videos, read tutorials, and get access to the Training Kit to help get you started learning LightSwitch. The home page also features other goodies like LightSwitch blogs and Channel 9 interviews.

You also should notice new “Library”, “Learn” and “Forums” tabs at the top of the page that you can explore:

image

Our new Learn page has How Do I videos that we’ll be releasing each week, as well as links to important learning resources like Code Samples, featured library articles, and the Training Kit. Stay tuned into this page as we build up more learning content!

So please download the Beta 1, explore the LightSwitch Developer Center and give us your feedback and ask questions in the forums.

Enjoy!

by Beth Massi at August 23, 2010 07:47 PM

Alex Feldstein

Golden Years Of British Comedy: The Swinging Sixties

<object height="355" width="425"><param name="movie" value="http://www.youtube.com/v/K2k1iRD2f-c?fs=1&amp;hl=en_US&amp;hl=en"><embed height="355" src="http://www.youtube.com/v/K2k1iRD2f-c?fs=1&amp;hl=en_US&amp;hl=en" type="application/x-shockwave-flash" width="425"></embed></object>

YouTube link

by Alex Feldstein (noreply@blogger.com) at August 23, 2010 10:54 AM

Flying aboard the Lockheed Constellation

<object height="385" width="640"><param name="movie" value="http://www.youtube.com/v/F6MTfjAQyy0&amp;rel=0&amp;color1=0xb1b1b1&amp;color2=0xd0d0d0&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed allowfullscreen="true" allowscriptaccess="always" height="385" src="http://www.youtube.com/v/F6MTfjAQyy0&amp;rel=0&amp;color1=0xb1b1b1&amp;color2=0xd0d0d0&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" width="640"></embed></object>

Flying aboard the Lockheed Constellation part 1

<object height="385" width="640"><param name="movie" value="http://www.youtube.com/v/fquT_b9OSAE&amp;rel=0&amp;color1=0xb1b1b1&amp;color2=0xd0d0d0&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed allowfullscreen="true" allowscriptaccess="always" height="385" src="http://www.youtube.com/v/fquT_b9OSAE&amp;rel=0&amp;color1=0xb1b1b1&amp;color2=0xd0d0d0&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" width="640"></embed></object>

Flying aboard the Lockheed Constellation part 2

by Alex Feldstein (noreply@blogger.com) at August 23, 2010 10:31 AM

August 22, 2010

Alex Feldstein

Farnborough Air Show 1950

<object height="385" width="640"><param name="movie" value="http://www.youtube.com/v/WbAqyHRSS8w&amp;rel=0&amp;color1=0xb1b1b1&amp;color2=0xd0d0d0&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed allowfullscreen="true" allowscriptaccess="always" height="385" src="http://www.youtube.com/v/WbAqyHRSS8w&amp;rel=0&amp;color1=0xb1b1b1&amp;color2=0xd0d0d0&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" width="640"></embed></object>

Farnborough Air Show 1950

by Alex Feldstein (noreply@blogger.com) at August 22, 2010 11:01 PM

Jack Horkheimer: Star Hustler 1938-2010

I just found out that Jack Horkheimer  a fixture in PBS for many years, and one of our  local contributors to PBS has passed away.

Here’s a link to the last show he did:

<object height="385" width="640"><param name="movie" value="http://www.youtube.com/v/9kCZYVOSNw8?fs=1&amp;hl=en_US"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed allowfullscreen="true" allowscriptaccess="always" height="385" src="http://www.youtube.com/v/9kCZYVOSNw8?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" width="640"></embed></object>

It is a pity that you had to concede to the PC forces and change the title of your show to Star Gazer. I kind of liked Star Hustler better.

So long Jack. We’ll miss you!

Keep looking up!

by Alex Feldstein (noreply@blogger.com) at August 22, 2010 04:21 PM

Photo of the Day


Fisher Island, viewed from the southern tip of Miami Beach

by Alex Feldstein (noreply@blogger.com) at August 22, 2010 09:12 AM

The Problem Solver

Workflows and no persist zones

There are times when a workflow can’t be persisted safely using a SqlWorkflowInstanceStore. The reason isn’t so much saving the state of  a workflow to disk, that could be done at any time, but the result when a workflow would be reloaded from disk in that state.

An easy example is a workflow handling a WCF request with a Receive and SendReply activity pair. Suppose you would save the workflow state after the message had been received but before the response had been send. No problem there. Now suppose the workflow is aborted just after the response is send and later the saved state is reloaded. The first action of the reloaded workflow would be to send the response again. But where? The connection is long gone and the client has seen the original response and is happy. Clearly this would fault the workflow again and for that reason the workflow is in a no persist zone starting at the Receive and ending at the SendReply activity.

But wait. The SendReply activity has a property named PersistBeforeSend, surely that means it will be persisted before the reply is send? Actually it doesn’t and it persists after the response has been send. So the property name is wrong? Not quite, although I believe it is poorly named, as the Persist activity is actually scheduled just before the response is send. But due to the asynchronous nature of workflow execution it doesn’t execute until after the response has actually been send and we are at a point where it would be save to reload the workflow.

So what happens of you try to persist a workflow in a no persist zone? You will get an exception with the following message:

Persist activities cannot be contained within no persistence blocks.

In this case all I did was drop a Persist activity between a Receive and SendReply activity pair, I didn’t even add or configure the SqlWorkflowInstanceStore itself.

 

Checking for a no persist zone

So how can we check if we are currently in a no persist zone? It turns out the NativeActivityContext has a property called IsInNoPersistScope that will tell us that, unfortunately the property is internal so we can’t use it [:(].

Turns out that duplicating this behavior is quite easy though. Whenever a no persist zone is started a NoPersistProperty is created and stored in the NativeActivityContext Properties collection. The NoPersistProperty is also internal but that is no problem as all we need to do if check if there is a object stored under the name "System.Activities.NoPersistProperty", something we can do with the following activity:

public class CheckForNoPersistZone : NativeActivity
{
    public OutArgument<bool> IsInNoPersistScope { get; set; }
 
    protected override void Execute(NativeActivityContext context)
    {
        var prop = context.Properties.Find("System.Activities.NoPersistProperty");
        IsInNoPersistScope.Set(context, prop != null);
    }
}

 

Creating our own no persist zones

Sometimes it might be required to stop a workflow from persisting and we can do so by creating our own no persist zone. There is no standard activity to do so but creating a pair of activities to do so isn’t hard. The basic building blocks are a NoPersistHandle and calling Enter() and Exit() on it to start and end the no persist zone. This could easily be done through a composite activity or through two separate activities. In the code below I have chosen for the approach with a single composite activities.

public class NoPersistZone : NativeActivity
{
    private Variable<NoPersistHandle> NoPersistHandle { get; set; }
    
    [RequiredArgument]
    public Activity Body { get; set; }
 
    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        NoPersistHandle = new Variable<NoPersistHandle>();
        metadata.AddImplementationVariable(NoPersistHandle);
 
        base.CacheMetadata(metadata);
    }
 
    protected override void Execute(NativeActivityContext context)
    {
        var noPersistHandle = NoPersistHandle.Get(context);
        noPersistHandle.Enter(context);
        context.ScheduleActivity(Body, OnCompleted);
    }
 
    private void OnCompleted(NativeActivityContext context, ActivityInstance completedInstance)
    {
        var noPersistHandle = NoPersistHandle.Get(context);
        noPersistHandle.Exit(context);
    }
}

 

Another nice activity to have for a generic toolbox.

 

Enjoy!

www.TheProblemSolver.nl
Wiki.WindowsWorkflowFoundation.eu

by Maurice at August 22, 2010 08:22 AM

August 21, 2010

Alex Feldstein

That Mitchell and Webb Look – The Aliens

<object height="355" width="425"><param name="movie" value="http://www.youtube.com/v/QyInKT95eG0&amp;color1=0xb1b1b1&amp;color2=0xd0d0d0&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1&amp;hl=en"><embed height="355" src="http://www.youtube.com/v/QyInKT95eG0&amp;color1=0xb1b1b1&amp;color2=0xd0d0d0&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1&amp;hl=en" type="application/x-shockwave-flash" width="425"></embed></object>

YouTube link

(via Cynical-C)

by Alex Feldstein (noreply@blogger.com) at August 21, 2010 10:41 AM

August 20, 2010

Alex Feldstein

Photo of the Day


On a visit to the Miami Seaplane Base (X44) on Watson Island, across the bay from downtown Miami a few days ago, I spotted this beautiful old Grumman Goose G-21A

by Alex Feldstein (noreply@blogger.com) at August 20, 2010 10:44 AM

August 19, 2010

Rick Strahl's Web Log

RequestValidation Changes in ASP.NET 4.0

There’s been a change in the way the ValidateRequest attribute on WebForms works in ASP.NET 4.0. I noticed this today while updating a post on my WebLog all of which contain raw HTML and so all pretty much trigger request validation. I recently upgraded this app from ASP.NET 2.0 to 4.0 and it’s now failing to update posts. At first this was difficult to track down because of custom error handling in my app – the custom error handler traps the exception and logs it with only basic error information so the full detail of the error was initially hidden.

After some more experimentation in development mode the error that occurs is the typical ASP.NET validate request error (‘A potentially dangerous Request.Form value was detetected…’) which looks like this in ASP.NET 4.0:

RequestValidationErrorScreen

At first when I got this I was real perplexed as I didn’t read the entire error message and because my page does have:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="NewEntry.aspx.cs" Inherits="Westwind.WebLog.NewEntry" 
         MasterPageFile="~/App_Templates/Standard/AdminMaster.master"  
         ValidateRequest="false"         
         EnableEventValidation="false"
         EnableViewState="false" 
%>

WTF? ValidateRequest would seem like it should be enough, but alas in ASP.NET 4.0 apparently that setting alone is no longer enough. Reading the fine print in the error explains that you need to explicitly set the requestValidationMode for the application back to V2.0 in web.config:

<httpRuntime executionTimeout="300" requestValidationMode="2.0" />

Kudos for the ASP.NET team for putting up a nice error message that tells me how to fix this problem, but excuse me why the heck would you change this behavior to require an explicit override to an optional and by default disabled page level switch? You’ve just made a relatively simple fix to a solution a nasty morass of hard to discover configuration settings??? The original way this worked was perfectly discoverable via attributes in the page. Now you can set this setting in the page and get completely unexpected behavior and you are required to set what effectively amounts to a backwards compatibility flag in the configuration file.

It turns out the real reason for the .config flag is that the request validation behavior has moved from WebForms pipeline down into the entire ASP.NET/IIS request pipeline and is now applied against all requests. Here’s what the breaking changes page from Microsoft says about it:

The request validation feature in ASP.NET provides a certain level of default protection against cross-site scripting (XSS) attacks. In previous versions of ASP.NET, request validation was enabled by default. However, it applied only to ASP.NET pages (.aspx files and their class files) and only when those pages were executing.

In ASP.NET 4, by default, request validation is enabled for all requests, because it is enabled before the BeginRequest phase of an HTTP request. As a result, request validation applies to requests for all ASP.NET resources, not just .aspx page requests. This includes requests such as Web service calls and custom HTTP handlers. Request validation is also active when custom HTTP modules are reading the contents of an HTTP request.

As a result, request validation errors might now occur for requests that previously did not trigger errors. To revert to the behavior of the ASP.NET 2.0 request validation feature, add the following setting in the Web.config file:

<httpRuntime requestValidationMode="2.0" />

However, we recommend that you analyze any request validation errors to determine whether existing handlers, modules, or other custom code accesses potentially unsafe HTTP inputs that could be XSS attack vectors.

Ok, so ValidateRequest of the form still works as it always has but it’s actually the ASP.NET Event Pipeline, not WebForms that’s throwing the above exception as request validation is applied to every request that hits the pipeline. Creating the runtime override removes the HttpRuntime checking and restores the WebForms only behavior. That fixes my immediate problem but still leaves me wondering especially given the vague wording of the above explanation.

One thing that’s missing in the description is above is one important detail: The request validation is applied only to application/x-www-form-urlencoded POST content not to all inbound POST data.

When I first read this this freaked me out because it sounds like literally ANY request hitting the pipeline is affected. To make sure this is not really so I created a quick handler:

public class Handler1 : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Write("Hello World <hr>" + context.Request.Form.ToString());
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

and called it with Fiddler by posting some XML to the handler using a default form-urlencoded POST content type:

FiddlerRequest

and sure enough – hitting the handler also causes the request validation error and 500 server response.

Changing the content type to text/xml effectively fixes the problem however, bypassing the request validation filter so Web Services/AJAX handlers and custom modules/handlers that implement custom protocols aren’t affected as long as they work with special input content types. It also looks that multipart encoding does not trigger event validation of the runtime either so this request also works fine:

POST http://rasnote/weblog/handler1.ashx HTTP/1.1
Content-Type: multipart/form-data; boundary=------7cf2a327f01ae
User-Agent: West Wind Internet Protocols 5.53
Host: rasnote
Content-Length: 40
Pragma: no-cache

<xml>asdasd</xml>--------7cf2a327f01ae

*That* probably should trigger event validation – since it is a potential HTML form submission, but it doesn’t.

New Runtime Feature, Global Scope Only?

Ok, so request validation is now a runtime feature but sadly it’s a feature that’s scoped to the ASP.NET Runtime – effective scope to the entire running application/app domain. You can still manually force validation using Request.ValidateInput() which gives you the option to do this in code, but that realistically will only work with the requestValidationMode set to V2.0 as well since the 4.0 mode auto-fires before code ever gets a chance to intercept the call. Given all that, the new setting in ASP.NET 4.0 seems to limit options and makes things more difficult and less flexible. Of course Microsoft gets to say ASP.NET is more secure by default because of it but what good is that if you have to turn off this flag the very first time you need to allow one single request that bypasses request validation??? This is really shortsighted design… <sigh>

© Rick Strahl, West Wind Technologies, 2005-2010
Posted in ASP.NET  
kick it on DotNetKicks.com

by Rick Strahl at August 19, 2010 08:40 PM

Alex Feldstein

Developer.Blog();

My first experience with Visual Studio LightSwitch

When Microsoft announced Visual Studio LightSwitch, I was pretty excited. Despite many gurus and non-gurus saying this was the end of the world, I saw LightSwitch as a great opportunity. Let me explain for a moment.

Fifteen to twenty years ago, FoxPro was a great end-user tool. It was great for developers, but end users could create quick and dirty applications with it. These applications solved real business problems in a short amount of time for little money. But at some point the business person realized they were in over their head and called on professional programmers to add functionality. Yes, the original program was a mess. Yes, it was often easier to start over, but the business user had gotten great use out of their creation, sometimes lasting years before they had to call in the pros. Many times these applications were ones that the business couldn’t afford to hire a pro in the first place. In the end, the use of these home-grown apps didn’t negatively affect the professional developer. In fact, I say it gave us more opportunity.

But FoxPro wasn’t the only tool used. Microsoft also had Access. FoxPro eventually morphed into Visual FoxPro and became a pure developer tool and today is no longer being updated by Microsoft. Access, on the other hand, continues to be sold. Thousands of Access applications exist in the same way thousands of FoxPro apps existed. The business user needed to solve a problem, in a hurry, with little cost. However, Access is morphing. Microsoft is pushing it to become a front-end tool for SharePoint development.

Where is the business user to go? They still need quick and dirty apps at a low cost to solve business problems. To fill this need, Microsoft created Visual Studio LightSwitch. It’s a version of Visual Studio customized for the business user. When you create applications, you use a simple designer to specify your data and screens. The VS templates handle the heavy lifting. The apps are created in Silverlight 4 and can be run locally or over the web. You can connect to different data sources and even export to Office. In reality, there is little difference between what the user can do with LightSwitch and what they’ve been doing for years with FoxPro or Access.

Since the announcment, I’ve been eagerly awaiting the release of the first Beta bits. And today was the day. And my first actual impression is not good. Originally I got compile errors on the Microsoft supplied Vision Clinic walk-through. An assembly or namespace from the generated code was missing. The reference was in the project, but I couldn’t manually modify the generated code. Fail #1.

I decided to try a different machine. I again downloaded the bits, ran the install, and started my way through Vision Clinic again. This time the compile succeeded and I was able get the first part of the application running. Success #1.

The next step instructed me to download the “PrescriptionContso” database from the “Connect” site. So, up to the Internet I went and searched the Connect site. No luck. How about code.msdn.com? Nope. CodePlex? Nope. Bing search? Nothing. Fail #2. At this point, I quit. I won’t go any further until the docs are fixed. Why not just provide a link to the download so people can find it?

I have some other observations. First, creating entities is a bit cumbersome. I have to click in the Add property field. I can’t just tab into it. Second, when you specify a datatype for the property, three of the choices are Int16, Int32, and Int64. The average business user won’t understand the difference between these and could actually choose the wrong one. I also got the properties in the wrong order. I put LastName before FirstName when creating the Entity. I couldn’t find a way to move them. Because the generator puts the properties in the order specified in the Entity, this is a problem. Finally, the walk-through has you create a couple of  things callled a “Choice List”. It’s really a pick list mechanism. The first time a Choice List is specified, you are instructed to use values 1-3. The second time it’s 0-2. No explanation as to why this is different. Again, an average business user won’t understand this. The walk-through should provide some type of explanation about what the values mean.

I understand this is Beta 1 and changes will be made, but right now, I’m stopped because the docs are not ready to go. I still have great hope for LightSwitch and see it as a valuable business tool. I just hope Microsoft at least gets the documentation fixed soon.

by Craig Berntson at August 19, 2010 02:44 AM

August 18, 2010

Beth Massi - Sharing the goodness that is VB

LightSwitch Beta 1 Available to MSDN Subscribers Today, General Public on Monday

We just released Visual Studio LightSwitch Beta 1 to MSDN subscribers. Public availability will be this Monday, August 23rd but if you are an MSDN subscriber visit your subscriptions page to get access to the download now. Otherwise check the the LightSwitch Developer Center on Monday for the public download.

Here are some resources to help get you started -- we have a lot more for you on Monday via the Dev Center so stay tuned!

We're looking forward to your feedback, please visit the forums.

I have to say I have been having a ball creating How Do I videos for LightSwitch this week and exploring and learning the product. We're planning on a re-vamp of the LightSwitch Dev Center on Monday and the videos (plus a lot of other content) will be available at that time with links to the public download when available.

Cant wait!

by Beth Massi at August 18, 2010 09:34 PM

Doug Hennig

Two Great Reasons to Attend Southwest Fox

Kevin Ragsdale blogged about two good reasons to attend Southwest Fox this year. His reasons were the previews Bo Durban and Steve Ellenoff give for their Southwest Fox sessions. I especially liked these comments:

“During Bo’s session, my mind was spinning with new ways of approaching the web browser control in my apps. I couldn’t wait to get home so I could start working on them. Some of them I’ve already tried, and the speed increase on displaying HTML in my app is incredible. And this means Bo’s session alone is worth the cost of the conference to me.”

“In short, Steve’s done a ton of work that I have avoided like the plague.”

Of course, I think there’s a lot more than two good reasons: more like 200! One for each session (you learn a lot in each one), one for each speaker (you get to hang out with and pick the brains of the brightest VFP developers on the planet for free!), one for each attendee (networking with other developers is one of the most important reasons to attend any conference), plus the food, the fun (don’t forget go-karts this year!), and the gorgeous Phoenix weather.

If you haven’t already registered for Southwest Fox, check out the session line-up and who else is coming that you might like to meet or renew acquaintances with, then sign up for Southwest Fox before the September 1 early-bird deadline.

by Doug Hennig (noreply@blogger.com) at August 18, 2010 09:24 PM

Andrew MacNeill - AKSEL Solutions

Simple But Useful VFP Tip: Remote Views with SQL Server varchar fields

Note: This is a feature that's been in VFP for years - but I've often found that useful features often remain hidden until someone points them out. So I'm taking to finding my little VFP tips as I come across them and re-posting them here.

I work in a variety of environments but one thing I always keep with me on my USB drive is VFP. Regardless of the data I have to work with, I always find that a task comes up that is infinitely easier in VFP. The funny thing is that other colleagues on a team who haven't been exposed to VFP are usually amazed at how quickly stuff can be done.

Today, I was working with a SQL Server table and SSMS only lets you edit the first 200 rows on their own - otherwise you have to script it (or use another tool).

For most of these systems, I typically create a VFP Database Container and then create remote views as necessary.

Oftentimes, the problem is that when VFP comes across a varchar field that is longer than 254 characters, it immediately converts it into a memo field so I am left with something like this:


This is annoying as the field I really need to modify is the DisplayText column or the Memo field and while I can open it, I would prefer to be lazy on this end.

So in the View designer, highlight the desired field and choose Properties. Then change the Data Type of your output of choice. Since most of my text in this column will be less than 254 chars, I'm just making that change here.

Now, when I browse my remote table, I can see the contents of the field, make changes and they propagate right back to the SQL table.


Nice and simple.




by Andrew MacNeill (noreply@blogger.com) at August 18, 2010 12:16 PM

Alex Feldstein

August 17, 2010

Rick Strahl's Web Log

Microsoft Introduces WebMatrix

originally published in CoDe Magazine Editorial

Microsoft recently released the first CTP of a new development environment called WebMatrix, which along with some of its supporting technologies are squarely aimed at making the Microsoft Web Platform more approachable for first-time developers and hobbyists. But in the process, it also provides some updated technologies that can make life easier for existing .NET developers.

Let’s face it: ASP.NET development isn’t exactly trivial unless you already have a fair bit of familiarity with sophisticated development practices. Stick a non-developer in front of Visual Studio .NET or even the Visual Web Developer Express edition and it’s not likely that the person in front of the screen will be very productive or feel inspired. Yet other technologies like PHP and even classic ASP did provide the ability for non-developers and hobbyists to become reasonably proficient in creating basic web content quickly and efficiently.

WebMatrix appears to be Microsoft’s attempt to bring back some of that simplicity with a number of technologies and tools. The key is to provide a friendly and fully self-contained development environment that provides all the tools needed to build an application in one place, as well as tools that allow publishing of content and databases easily to the web server.

WebMatrix is made up of several components and technologies:

IIS Developer Express

IIS Developer Express is a new, self-contained development web server that is fully compatible with IIS 7.5 and based on the same codebase that IIS 7.5 uses. This new development server replaces the much less compatible Cassini web server that’s been used in Visual Studio and the Express editions. IIS Express addresses a few shortcomings of the Cassini server such as the inability to serve custom ISAPI extensions (i.e., things like PHP or ASP classic for example), as well as not supporting advanced authentication. IIS Developer Express provides most of the IIS 7.5 feature set providing much better compatibility between development and live deployment scenarios.

SQL Server Compact 4.0

Database access is a key component for most web-driven applications, but on the Microsoft stack this has mostly meant you have to use SQL Server or SQL Server Express. SQL Server Compact is not new-it’s been around for a few years, but it’s been severely hobbled in the past by terrible tool support and the inability to support more than a single connection in Microsoft’s attempt to avoid losing SQL Server licensing. The new release of SQL Server Compact 4.0 supports multiple connections and you can run it in ASP.NET web applications simply by installing an assembly into the bin folder of the web application. In effect, you don’t have to install a special system configuration to run SQL Compact as it is a drop-in database engine: Copy the small assembly into your BIN folder (or from the GAC if installed fully), create a connection string against a local file-based database file, and then start firing SQL requests.

Additionally WebMatrix includes nice tools to edit the database tables and files, along with tools to easily upsize (and hopefully downsize in the future) to full SQL Server.

This is a big win, pending compatibility and performance limits. In my simple testing the data engine performed well enough for small data sets. This is not only useful for web applications, but also for desktop applications for which a fully installed SQL engine like SQL Server would be overkill. Having a local data store in those applications that can potentially be accessed by multiple users is a welcome feature.

ASP.NET Razor View Engine

What? Yet another native ASP.NET view engine? We already have Web Forms and various different flavors of using that view engine with Web Forms and MVC. Do we really need another? Microsoft thinks so, and Razor is an implementation of a lightweight, script-only view engine. Unlike the Web Forms view engine, Razor works only with inline code, snippets, and markup; therefore, it is more in line with current thinking of what a view engine should represent. There’s no support for a “page model” or any of the other Web Forms features of the full-page framework, but just a lightweight scripting engine that works with plain markup plus embedded expressions and code.

The markup syntax for Razor is geared for minimal typing, plus some progressive detection of where a script block/expression starts and ends. This results in a much leaner syntax than the typical ASP.NET Web Forms alligator (<% %>) tags. Razor uses the @ sign plus standard C# (or Visual Basic) block syntax to delineate code snippets and expressions.

Here’s a very simple example of what Razor markup looks like along with some comment annotations:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
    </head>
    <body>
    <h1>Razor Test</h1>
    
    <!-- simple expressions -->
    @DateTime.Now

    <hr />

    <!-- method expressions -->
    @DateTime.Now.ToString("T")
    
    <!-- code blocks -->
    @{
        List<string> names = new List<string>();
        names.Add("Rick");
        names.Add("Markus");
        names.Add("Claudio");
        names.Add("Kevin");
    }
    
    <!-- structured block statements -->
    <ul>
    @foreach(string name in names){
            <li>@name</li>
    }
    </ul>
      
   <!-- Conditional code -->    
   @if(true) {                
       <!-- Literal Text embedding in code -->
       <text>
        true
       </text>;
   }
   else
   {
       <!-- Literal Text embedding in code -->
      <text>
      false
      </text>;
   }

   </body>
</html>

Like the Web Forms view engine, Razor parses pages into code, and then executes that run-time compiled code. Effectively a “page” becomes a code file with markup becoming literal text written into the Response stream, code snippets becoming raw code, and expressions being written out with Response.Write(). The code generated from Razor doesn’t look much different from similar Web Forms code that only uses script tags; so although the syntax may look different, the operational model is fairly similar to the Web Forms engine minus the overhead of the large Page object model. However, there are differences: -Razor pages are based on a new base class, Microsoft.WebPages.WebPage, which is hosted in the Microsoft.WebPages assembly that houses all the Razor engine parsing and processing logic. Browsing through the assembly (in the generated ASP.NET Temporary Files folder or GAC) will give you a good idea of the functionality that Razor provides. If you look closely, a lot of the feature set matches ASP.NET MVC’s view implementation as well as many of the helper classes found in MVC.

It’s not hard to guess the motivation for this sort of view engine: For beginning developers the simple markup syntax is easier to work with, although you obviously still need to have some understanding of the .NET Framework in order to create dynamic content. The syntax is easier to read and grok and much shorter to type than ASP.NET alligator tags (<% %>) and also easier to understand aesthetically what’s happening in the markup code.

Razor also is a better fit for Microsoft’s vision of ASP.NET MVC: It’s a new view engine without the baggage of Web Forms attached to it. The engine is more lightweight since it doesn’t carry all the features and object model of Web Forms with it and it can be instantiated directly outside of the HTTP environment, which has been rather tricky to do for the Web Forms view engine. Having a standalone script parser is a huge win for other applications as well – it makes it much easier to create script or meta driven output generators for many types of applications from code/screen generators, to simple form letters to data merging applications with user customizability. For me personally this is very useful side effect and who knows maybe Microsoft will actually standardize they’re scripting engines (die T4 die!) on this engine.

Razor also better fits the “view-based” approach where the view is supposed to be mostly a visual representation that doesn’t hold much, if any, code. While you can still use code, the code you do write has to be self-contained. Overall I wouldn’t be surprised if Razor will become the new standard view engine for MVC in the future – and in fact there have been announcements recently that Razor will become the default script engine in ASP.NET MVC 3.0.

Razor can also be used in existing Web Forms and MVC applications, although that’s not working currently unless you manually configure the script mappings and add the appropriate assemblies. It’s possible to do it, but it’s probably better to wait until Microsoft releases official support for Razor scripts in Visual Studio. Once that happens, you can simply drop .cshtml and .vbhtml pages into an existing ASP.NET project and they will work side by side with classic ASP.NET pages.

WebMatrix Development Environment

To tie all of these three technologies together, Microsoft is shipping WebMatrix with an integrated development environment. An integrated gallery manager makes it easy to download and load existing projects, and then extend them with custom functionality. It seems to be a prominent goal to provide community-oriented content that can act as a starting point, be it via a custom templates or a complete standard application.

The IDE includes a project manager that works with a single project and provides an integrated IDE/editor for editing the .cshtml and .vbhtml pages. A run button allows you to quickly run pages in the project manager in a variety of browsers. There’s no debugging support for code at this time. Note that Razor pages don’t require explicit compilation, so making a change, saving, and then refreshing your page in the browser is all that’s needed to see changes while testing an application locally. It’s essentially using the auto-compiling Web Project that was introduced with .NET 2.0. All code is compiled during run time into dynamically created assemblies in the ASP.NET temp folder.

WebMatrix also has PHP Editing support with syntax highlighting. You can load various PHP-based applications from the WebMatrix Web Gallery directly into the IDE. Most of the Web Gallery applications are ready to install and run without further configuration, with Wizards taking you through installation of tools, dependencies, and configuration of the database as needed. WebMatrix leverages the Web Platform installer to pull the pieces down from websites in a tight integration of tools that worked nicely for the four or five applications I tried this out on. Click a couple of check boxes and fill in a few simple configuration options and you end up with a running application that’s ready to be customized. Nice!

You can easily deploy completed applications via WebDeploy (to an IIS server) or FTP directly from within the development environment. The deploy tool also can handle automatically uploading and installing the database and all related assemblies required, making deployment a simple one-click install step.

Simplified Database Access

The IDE contains a database editor that can edit SQL Compact and SQL Server databases. There is also a Database helper class that facilitates database access by providing easy-to-use, high-level query execution and iteration methods:

@{  
    var db = Database.OpenFile("FirstApp.sdf");
    string sql = "select * from customers where Id > @0";
}


<ul>
@foreach(var row in db.Query(sql,1)){
        <li>@row.FirstName @row.LastName</li>
}
</ul>

The query function takes a SQL statement plus any number of positional (@0,@1 etc.) SQL parameters by simple values. The result is returned as a collection of rows which in turn have a row object with dynamic properties for each of the columns giving easy (though untyped) access to each of the fields.

Likewise Execute and ExecuteNonQuery allow execution of more complex queries using similar parameter passing schemes. Note these queries use string-based queries rather than LINQ or Entity Framework’s strongly typed LINQ queries. While this may seem like a step back, it’s also in line with the expectations of non .NET script developers who are quite used to writing and using SQL strings in code rather than using OR/M frameworks. The only question is why was something not included from the beginning in .NET and Microsoft made developers build custom implementations of these basic building blocks.

The implementation looks a lot like a DataTable-style data access mechanism, but to be fair, this is a common approach in scripting languages. This type of syntax that uses simple, static, data object methods to perform simple data tasks with one line of code are common in scripting languages and are a good match for folks working in PHP/Python, etc. Seems like Microsoft has taken great advantage of .NET 4.0’s dynamic typing to provide this sort of interface for row iteration where each row has properties for each field.

FWIW, all the examples demonstrate using local SQL Compact files - I was unable to get a SQL Server connection string to work with the Database class (the connection string wasn’t accepted). However, since the code in the page is still plain old .NET, you can easily use standard ADO.NET code or even LINQ or Entity Framework models that are created outside of WebMatrix in separate assemblies as required.

The good the bad the obnoxious - It’s still .NET

The beauty (or curse depending on how you look at it :)) of Razor and the compilation model is that, behind it all, it’s still .NET. Although the syntax may look foreign, it’s still all .NET behind the scenes. You can easily access existing tools, helpers, and utilities simply by adding them to the project as references or to the bin folder. Razor automatically recognizes any assembly reference from assemblies in the bin folder.

In the default configuration, Microsoft provides a host of helper functions in a Microsoft.WebPages assembly (check it out in the ASP.NET temp folder for your application), which includes a host of HTML Helpers. If you’ve used ASP.NET MVC before, a lot of the helpers should look familiar. Documentation at the moment is sketchy-there’s a very rough API reference you can check out here: http://www.asp.net/webmatrix/tutorials/asp-net-web-pages-api-reference

Who needs WebMatrix? Uhm… good Question

Clearly Microsoft is trying hard to create an environment with WebMatrix that is easy to use for newbie developers. The goal seems to be simplicity in providing a minimal development environment and an easy-to-use script engine/language that makes it easy to get started with. There’s also some focus on community features that can be used as starting points, such as Web Gallery applications and templates. The community features in particular are very nice and something that would be nice to eventually see in Visual Studio as well.

The question is whether this is too little too late. Developers who have been clamoring for a simpler development environment on the .NET stack have mostly left for other simpler platforms like PHP or Python which are catering to the down and dirty developer. Microsoft will be hard pressed to win those folks-and other hardcore PHP developers-back. Regardless of how much you dress up a script engine fronted by the .NET Framework, it’s still the .NET Framework and all the complexity that drives it. While .NET is a fine solution in its breadth and features once you get a basic handle on the core features, the bar of entry to being productive with the .NET Framework is still pretty high. The MVC style helpers Microsoft provides are a good step in the right direction, but I suspect it’s not enough to shield new developers from having to delve much deeper into the Framework to get even basic applications built.

Razor and its helpers is trying to make .NET more accessible but the reality is that in order to do useful stuff that goes beyond the handful of simple helpers you still are going to have to write some C# or VB or other .NET code. If the target is a hobby/amateur/non-programmer the learning curve isn’t made any easier by WebMatrix it’s just been shifted a tad bit further along in your development endeavor when you run out of canned components that are supplied either by Microsoft or the community.

The database helpers are interesting and actually I’ve heard a lot of discussion from various developers who’ve been resisting .NET for a really long time perking up at the prospect of easier data access in .NET than the ridiculous amount of code it takes to do even simple data access with raw ADO.NET. It seems sad that such a simple concept and implementation should trigger this sort of response (especially since it’s practically trivial to create helpers like these or pick them up from countless libraries available), but there it is. It also shows that there are plenty of developers out there who are more interested in ‘getting stuff done’ easily than necessarily following the latest and greatest practices which are overkill for many development scenarios. Sometimes it seems that all of .NET is focused on the big life changing issues of development, rather than the bread and butter scenarios that many developers are interested in to get their work accomplished. And that in the end may be WebMatrix’s main raison d'être: To bring some focus back at Microsoft that simpler and more high level solutions are actually needed to appeal to the non-high end developers as well as providing the necessary tools for the high end developers who want to follow the latest and greatest trends.

The current version of WebMatrix hits many sweet spots, but it also feels like it has a long way to go before it really can be a tool that a beginning developer or an accomplished developer can feel comfortable with. Although there are some really good ideas in the environment (like the gallery for downloading apps and components) which would be a great addition for Visual Studio as well, the rest of the development environment just feels like crippleware with required functionality missing especially debugging and Intellisense, but also general editor support. It’s not clear whether these are because the product is still in an early alpha release or whether it’s simply designed that way to be a really limited development environment. While simple can be good, nobody wants to feel left out when it comes to necessary tool support and WebMatrix just has that left out feeling to it.

If anything WebMatrix’s technology pieces (which are really independent of the WebMatrix product) are what are interesting to developers in general. The compact IIS implementation is a nice improvement for development scenarios and SQL Compact 4.0 seems to address a lot of concerns that people have had and have complained about for some time with previous SQL Compact implementations.

By far the most interesting and useful technology though seems to be the Razor view engine for its light weight implementation and it’s decoupling from the ASP.NET/HTTP pipeline to provide a standalone scripting/view engine that is pluggable. The first winner of this is going to be ASP.NET MVC which can now have a cleaner view model that isn’t inconsistent due to the baggage of non-implemented WebForms features that don’t work in MVC. But I expect that Razor will end up in many other applications as a scripting and code generation engine eventually.

Visual Studio integration for Razor is currently missing, but is promised for a later release. The ASP.NET MVC team has already mentioned that Razor will eventually become the default MVC view engine, which will guarantee continued growth and development of this tool along those lines. And the Razor engine and support tools actually inherit many of the features that MVC pioneered, so there’s some synergy flowing both ways between Razor and MVC.

As an existing ASP.NET developer who’s already familiar with Visual Studio and ASP.NET development, the WebMatrix IDE doesn’t give you anything that you want. The tools provided are minimal and provide nothing that you can’t get in Visual Studio today, except the minimal Razor syntax highlighting, so there’s little need to take a step back. With Visual Studio integration coming later there’s little reason to look at WebMatrix for tooling.

It’s good to see that Microsoft is giving some thought about the ease of use of .NET as a platform For so many years, we’ve been piling on more and more new features without trying to take a step back and see how complicated the development/configuration/deployment process has become. Sometimes it’s good to take a step - or several steps - back and take another look and realize just how far we’ve come. WebMatrix is one of those reminders and one that likely will result in some positive changes on the platform as a whole.

© Rick Strahl, West Wind Technologies, 2005-2010
Posted in ASP.NET   IIS7  
kick it on DotNetKicks.com

by Rick Strahl at August 17, 2010 10:44 PM

Alex Feldstein