Official BV Software Blog
New, Updates and Anything else we find interesting

Generate a Customer List for BV Commerce 5

March 26, 2008 15:50 by mmcconnell1618

If you've ever needed to get a quick export of everyone who has purchased from your store in the last year this SQL script can be used to generate a comma separated text file. Make sure you change the "> date" part to be the correct starting point for your export. You'll get customers' names, address, phone and email as long as they placed an order on your store.

 

SELECT 'LastName, FirstName, Line1, Line2, City,

        RegionName, PostalCode, CountryName,

        Phone, Email' AS Expr1, 0 AS [Order]

UNION

SELECT   CAST(CAST(AddressBook AS xml ).query(N'/AddressBook/Address[last()]/LastName/text()') AS nvarchar(1000))

+ ', ' + CAST(CAST(AddressBook AS xml ).query(N'/AddressBook/Address[last()]/FirstName/text()') AS nvarchar(1000))

+ ', ' + CAST(CAST(AddressBook AS xml ).query(N'/AddressBook/Address[last()]/Line1/text()') AS nvarchar(1000))

+ ', ' + CAST(CAST(AddressBook AS xml ).query(N'/AddressBook/Address[last()]/tLine2/text()') AS nvarchar(1000))

+ ', ' + CAST(CAST(AddressBook AS xml ).query(N'/AddressBook/Address[last()]/City/text()') AS nvarchar(1000))

+ ', ' + CAST(CAST(AddressBook AS xml ).query(N'/AddressBook/Address[last()]/RegionName/text()') AS nvarchar(1000))

+ ', ' + CAST(CAST(AddressBook AS xml ).query(N'/AddressBook/Address[last()]/PostalCode/text()') AS nvarchar(1000))

+ ', ' + CAST(CAST(AddressBook AS xml ).query(N'/AddressBook/Address[last()]/CountryName/text()') AS nvarchar(1000))

+ ', ' + CAST(CAST(AddressBook AS xml ).query(N'/AddressBook/Address[last()]/Phone/text()') AS nvarchar(1000))

+ ', ' + Email AS Expr1, 1 AS [Order]

FROM   bvc_User

WHERE (bvin IN

          (SELECT DISTINCT UserId

           FROM         bvc_Order

           WHERE (OrderNumber <> '') AND (TimeOfOrder > '01/01/2007')))

ORDER BY [Order]

 Run this in SQL Management Studio and then copy and paste the results to a text file. You can open the text file in Excel as "comma separated" (CSV) to get sort the data or mail merge.

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

JQuery 1.2.3 conflicts with Google Analytics

March 19, 2008 17:42 by mmcconnell1618

I was watching our Google Analytics traffic last week and noticed a sharp decline. My first thought was "My God, we've been blacklisted by Google or another search engine." I couldn't figure out why our traffic had dropped so dramatically. If it had dropped to zero I would have instantly thought the tracking script was at fault but instead it just dropped but kept counting with day to day variations.

I discovered that IE was reporting a script error and that was the clue to the mystery. We had added the JQuery library version 1.2.3 to our master page for some fancy image swapping. It turns out that this particular version of JQuery has an odd way of handling some click events and it conflicts with click handlers in Google Analytics. Apparently it doesn't happen all the time and it doesn't happen in all browsers so that's why we were still seeing some traffic records.

I pulled JQuery until it's patched and the stats popped back to normal the next day. Whew!

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

How to create a Dynamic LINQ Query Programmatically

February 27, 2008 21:14 by mmcconnell1618

If you've been stuggling to create a dynamic LINQ query you're not alone. Thanks to some research, hard work and a smart co-worker I was able to implement some cool dynamic LINQ code in our help desk application. 

In our helpdesk we have filter screens that look like this: 



Creating a LINQ query in challenging because we don't know ahead of time which fields the user will complete. They are all optional and without anything selected we want to pull back all tickets. Normally, you'd write a query like this:

 

var ticket = (from t in db.cerberus_Tickets

                          where t.id == id

                          select t).Single();

In the example above we know that the t.id parameter will always be given. So how do you create a query in code when you don't know what fields to include in the WHERE clause ahead of time?

The first key is understanding the LINQ queries are not executed until they are used to enumerate through a collection. This part is key because it means we can create a query and change it in code as long as we don't try to look at the results first.

What we're going to do is create an IQueryable collection that contains all of our Ticket objects and we'll dynamically add our WHERE clause information.  Then we'll create a normal LINQ query that selects all of the matches from our IQueryable collection and handles paging. Because we don't actually enumerate the IQueryable collection that contains all our tickets, it won't actually pull back all of the tickets (which would take forever!). Instead, it will be "merged" with our normally LINQ query at run time when we enumerate over it.

1) Create our LINQ to SQL context objects

 

 

 List<cerberus_Ticket> result = new List<cerberus_Ticket>();

 cerberusDataContext db = new cerberusDataContext(connectionString);

 

2) Create an empty IQueryable collection containing all tickets. Note that this query doesn't actually select everything from the database yet. If it did this would take forever and effectively be filtering the database table in memory. That would not be a good design!

 

 

 IQueryable<cerberus_Ticket> matches = db.cerberus_Tickets;

 

3) Add our WHERE clause information with custom logic to decide if the clauses should be added or not

 

       

 if (this.AgentIdField.Text.Trim().Length > 0)

 {

     matches = matches.Where(a => a.AgentId == criteria.AgentId);

 }

 

 if (this.TicketIdField.Text.Trim().Length > 0)

 {

     matches = matches.Where(a => a.TicketId.Contains(criteria.TicketId));

 }

 

 4) Create a second LINQ query that selects from the first one to sort and page the results.

 

 // calculate start row based on page parameters passed in

 int startRow = (pageNumber - 1) * pageSize;

 

 var output = (from p in matches

               orderby p.DateCreated descending

               select p).Skip(startRow).Take(pageSize).ToList();

 

 

Again, I can't emphasize enough how cool it is that LINQ doesn't query the database until we call the ToList() at the end of the second statement. This delay in execution is the magic that lets us create dynamic queries on the fly.

Have any cool LINQ tips of your own to share?

 

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Quick program to batch rename files to replace text

February 23, 2008 14:42 by mmcconnell1618

Today I had a huge directory of 300+ images that I batch converted in Photoshop from TIFF to PNG format. The problem was I must have missed something in Photoshop and all the files came out like this:

 Image1.TIFF.PNG

I needed to remove the ".TIFF" part from the name so I wrote a quick c# command line program to look at a directory, find all files that contained text in their name and replace that with something else. It's a quick and dirty solution but I thought someone else might need it. The source directory, text to find and text to replace are just string in the source code. You may want to move them out to command line parameters if you need this kind of program often.

Here's the source code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

 

namespace FileNameChanger

{

    class Program

    {

        static void Main(string[] args)

        {

            /*

            * Change these three settings to tell the program

            * where to search, what to find and what to replace

            * it with

            */

            string sourceDir = @"C:\Users\mmcconnell\Desktop\CroppedTiff\PNG";

            string stringToFind = ".tiff.png";

            string stringToReplace = ".png";

 

            if (Directory.Exists(sourceDir))

            {

                string[] thefiles = Directory.GetFiles(sourceDir);

                if (thefiles != null)

                {

                    foreach (string f in thefiles)

                    {

                        string pathPart = Path.GetDirectoryName(f);

                        string filePart = Path.GetFileName(f);

                        filePart = filePart.Replace(stringToFind, stringToReplace);

                        File.Move(f, Path.Combine(pathPart, filePart));

 

                        Console.WriteLine("Moving to " + filePart);

                    }

                }

            }

        }

    }

}

 

 

 

Program.cs (1.26 kb)


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5