This link is a wiki for Live Templates that you can install in your copy of Delphi. If you come up with your own cool Live Templates, you can add them there, too.
I had a need to write SQL to answer the question "How many times in a row have I scored -20 or better?" in a game of Golden Tee. I have the raw data stored in a table that has these fields (and more, but they aren't important to this exercise).
tblContestResults
ContestId Long Integer
Score Integer
I didn't want to use a cursor, and I wanted to stay as close to ANSI SQL as possible (so no stored procs, etc.). After googling around a bit, I came across this link that showed how to do this all in SQL using nested selects and virtual groups. The sample was written to be compatible with MSSQL. After tweaking it just a bit, I came to this solution, which works wonderfully.
SELECT Max(grpCnt) AS MaxRun
FROM (Select grp, Count(*) As GrpCnt
From
(Select A.ContestId, A.Score,
Case
When A.Score <= -20 Then
Isnull( (Select Max(B.ContestId) From tblContestResults As B
Where B.ContestId < A.ContestId and B.Score>-20),
(Select Min(C.ContestId) from tblContestResults AS C) )
End As grp
From tblContestResults As A) As WithGrps
Where grp Is Not Null
Group By grp) AS WithGrpCnts;
You can take each of the nested selects out and break them apart to execute them in order to see how the query is built up. Quite an interesting technique, and one that I will definitely keep in my bag of tricks. For my purposes, I had to use MS Access, so that meant I had to change things in the SQL a bit more since there is no "CASE WHEN" in Access. The following is the code I ended up using, and it also works quite well. I didn't use the nz() function because there is a problem in Delphi's TADODataset when executing code that has that expression in it (more on that later). Using nz() does work in Access, and makes the query easier to read, IMO. But if it doesn't work in Delphi, then I can't use it.
SELECT MAX(grpCnt) AS MaxRun
FROM (SELECT grp, Count(*) as GrpCnt
FROM
(SELECT A.ContestID, A.Score,
IIf(A.Score<=-20,
IIf(
isnull((Select Max(B.ContestId) From tblContestResults As B Where B.ContestId < A.ContestId and B.Score>-20))
,(Select Min(C.ContestId) from tblContestResults AS C)
,(Select Max(B.ContestId) From tblContestResults As B Where B.ContestId < A.ContestId and B.Score>-20)
)
,Null) AS grp
FROM tblContestResults AS A
ORDER BY ContestId) as WithGrps
WHERE grp is not null
GROUP BY grp) AS WithGrpCnts;
When importing data into Excel, the data that you set will be treated as a Text cell by default. Dates in Excel are equivalent to Delphi TDateTime in that they are a julian date and time is stored as a fraction and share the same numeric equivalents after 3/1/1900 (integer value of 61). This makes life very simple when writing date values to your worksheet since you just need to write the TDateTime value to Excel and if you format the cell as a date, you get the date/time in the worksheet.
procedure TForm1.Button1Click(Sender: TObject);
var
Excel, Workbook, Worksheet: OleVariant;
begin
Excel := CreateOLEObject('Excel.Application');
try
WorkBook := Excel.WorkBooks.Open('c:\temp\ws.xls');
WorkSheet := WorkBook.Worksheets.Item['Sheet1'];
WorkSheet.Range['A1', 'A1'].Value := Now;
finally
Excel.Quit;
Worksheet := Unassigned;
Workbook := Unassigned;
Excel := Unassigned;
end;
end;
For quite some time, Delphi has allowed custom FormatSettings to be used with many date/time functions. This allows you to use custom date/time settings within an application without changing the Windows options. For example, if you used this code snippet and had a date/time format like mm/dd/yyyy, you would see the date/time reported in the new format instead:
procedure TForm3.Button1Click(Sender: TObject);
var
MySettings: TFormatSettings;
s: string;
d: TDateTime;
begin
GetLocaleFormatSettings(GetUserDefaultLCID, MySettings);
MySettings.DateSeparator := '-';
MySettings.TimeSeparator := ':';
MySettings.ShortDateFormat := 'mm-dd-yyyy';
MySettings.ShortTimeFormat := 'hh:nn:ss';
s := DateTimeToStr(Now, MySettings);
ShowMessage(s);
d := StrToDateTime(s, MySettings);
ShowMessage(DateTimeToStr(d, MySettings));
end;
However, if you used 'mmm-dd-yyyy' as the ShortDateFormat in the example above (to display Jan-09-2006), you would get an error when calling StrToDateTime on this string. The workaround is to call d := VarToDateTime(s) instead, since that function supports month names when encoding the TDateTime. I logged this bug as QC 23301, so if you'd like to see this fixed, please rate this entry and vote on it if it's important enough to you.
I've been using VNC, including countless variants like UltraVNC and RealVNC, to access my home PC forever (OK, probably since around 1997 or so, so for the purposes of computer lifespans, that easily constitutes forever  ). I even moderate a (not-so-active) open source project called DelphiVNC. However, I tried Remote Desktop recently, and I immediately switched to it. My reasons for doing this were:
- Speed - RD seems much faster than VNC
- Easy file copy between systems
- Can stream remote sound to the local PC
- Easy to setup and configure
- Web access
Here are some of the links that I used to get things up and running:
- Good general overview of features from MS
- Getting access to local files in an RD session
- RD Web Connection setup will let you connect to the remote PC from the local PC via IE.
- How to use RD over SSH. This is a good FAQ for other RD items, too. It appears that as of XP SP2, you don't have to run in compatibility mode, at least as long as you try to connect to another port (e.g. 127.0.0.1:3390). Step 9 in this documnet means that you need to set up a SSH tunnel to forward from port 3390 to 3389. Pay close attention to the fact that you need to logout, though. If you don't do that when ending a session, you will need to reboot the remote PC to get RD working again.
If you go to a command prompt and type, "mstsc /?", you will see the different options you can pass in. I set up a few different RD profiles by selecting the Options button, filling out the details I wanted, and saving the profile. I then made shortcuts to pass in the rdp file to let me get quick and easy access to the remote PC.
Let me know how this works for you.
I don't have all of the details fleshed out yet, but thought I'd get you the heads up. It looks like John Kaster will be coming back to Milwaukee on March 16th, from 6:30-9:00, at the same Pewaukee Marriot hotel as last year. Stay tuned for more information. I'll also try to grab the list of names I had from last year to send out an email blast, but feel free to email me or leave a comment if you know definitely that you'll be in or out. Thanks.
John Kaster announced that Update 1 for BDS 2006 is now available. This update is supposed to bring the C++ personality out of preview mode, but since some of the files that changed are used by all personalities (IDE, TLE, etc.), I imagine some slight positive benefit will occur in the Delphi personalities as well.
There is an internal QC report that I created (21701) that deals with this issue. D2006 changed the behavior of TryEncodeDateTime (which is used by RecodeTime) so that it may return negative values when you don't expect it to. For example, a call like this returns a negative value: aDate := RecodeTime(0, 12, 0, 0, 0);
A snippet from the D2006 TryEncodeDateTime method looks like this:
Result := TryEncodeDate(AYear, AMonth, ADay, AValue);
if Result then
begin
Result := TryEncodeTime(AHour, AMinute, ASecond, AMilliSecond, LTime);
if Result then
if AValue > 0 then
AValue := AValue + LTime
else
AValue := AValue - LTime
I copied the methods I needed from DateUtils and made local copies and changed them to revert back to the code in D6. However, one person commented that performing the check, "if AValue >=0 then" would also work. Hopefully this gets fixed in Update 2.
Version 10.0.2151.25345 of midas.dll is available on my web site at http://www.distribucon.com/midas.html.
It should be backwards compatible with older Delphi versions. If you run into any problems with this new version, I highly recommend that you enter the issue into QC. MIDAS continues to get good bug fixes due in large part to people posting their issues in QC.
Have fun!
My co-worker, Jeff Chojnacki, bumped into this problem today. Basically, if you have a 2-tier setup with ClientDataset, DatasetProvider, SQLQuery, etc., and have code that looks similar to this:
cds1.Close;
q1.SQL.Text := 'SELECT * FROM COUNTRY WHERE COUNTRY LIKE :COUNTRY';
q1.Params.ParamByName('COUNTRY').AsString := eCountry.Text+'%';
cds1.Open;
you will find that the data in cds1 never updates. IOW, if you first pass an 'A', and then pass an 'F', the data will always return as if you are passing the 'A' param.
I used Jeff's test-case and did some debugging and found a work-around, and I believe, the true solution. The work-around is to just call cds1.Params.Clear after cds1.Close. The solution is that TDatsetProvider is returning ptInput Params improperly in DoGetRecords. For all of the gory details, see QC 22335. Hopefully this gets resolved in Update 2.
Bob Swart just posted this link to the DevCon05 videos. Not all sessions have Camtasia sessions, but this is a great start since Borland has never done anything even close to this before. John Kaster has mentioned before that QC ratings and comments help drive the funding and content on BDN. If you find this content the least bit valuable, take the time to comment and/or rate. Maybe next year we'll get Camtasia coverage for the entire conference!
I'll leave the fun of the Big Feature Writeups (e.g. Live Templates) to others in the blogoshpere that have already started to cover some of the new features of Delphi 2006. Instead, I'll cover some of the more mundane, but very useful new features of Delphi 2006.
Method navigation is described in the "What's New in Developer Studio 2006" file like this: "You can quickly navigate between methods in your source code using a series of hotkeys". You use hotkeys like CTRL+ALT+Up-arrow and CTRL+ATL+Down-arrow to move from one method to the next in a given unit. CTRL+ALT+Home and CTRL+ALT+End take you to the first and last method - respectively - in the unit. There is also the concept of Class Locking which will only let you navigate with those hotkeys within the current class. The documentation on how to toggle this feature is incorrect, though. The correct way to do this is to position your caret in the IDE somewhere in a class, then press CTRL+Q, followed by just the letter L. After you have enabled class lock, you are constrained to method navigation only within that class.
Note: This worked for me with the IDE Classic editor setting. I'm not sure how it works with other settings.
|