Advisor Answers. Clean up a Project. May, Visual FoxPro 9/8/7

Similar documents
Build Your Own Project Tools

VFP: Ideal for Tools, Part 3

Make Thor Your Own. Tamar E. Granor Tomorrow's Solutions, LLC Voice:

Zip it, Zip it Good Doug Hennig

and I want the subsets with three members, the result would be:

Session E-COLL Collections: Managing Information the Object-Oriented Way

Let's start by taking a look at the object generated by LIST OBJECTS. I used the following code to put a few objects in memory for testing:

Top 10 (or more) Reasons to Use the Toolbox

Try Thor s Terrific Tools

Working with the Registry. The Registry class makes it easy. The Registry Structure. January, By Tamar E. Granor

Q: I've been playing with the Microsoft Internet Transfer Control (inetctls.inet.1) and it would be great if only it worked.

Windows 7 Will Not Load On My Computer Says I'm

Give users a control that makes entering dates as easy as it is in Intuit Quicken.

Splitting a Procedure File

Advisor Answers. Create Cross-tabs. July, Visual FoxPro 9/8/7

A File Open Dialog Box Doug Hennig

New Language Features in Visual FoxPro 6.0

FoxcodePlus - New features for IntelliSense Microsoft Visual FoxPro 9 By Rodrigo D. Bruscain Version Beta Last updated May 26, 2013

Making the Most of the Toolbox

This tool lets you specify a new name for each control on a form or class and fixes all code that uses it.

Taking Advantage of Idle Cycles. Make Your Application Work When the User Isn't. The Idea. The Strategy. December, 2003

Advisor Answers. Creating New Sort Orders. June, Visual FoxPro 6.0, 5.0 and 3.0

Manage Your Applications Doug Hennig

Advisor Answers. January, Visual FoxPro 3.0 and 5.0

Basic Fiction Formatting for Smashwords in OpenOffice L. Leona Davis. Copyright 2012 L. Leona Davis All Rights Reserved

The Happy Project Hooker Doug Hennig

The computer goes blank before the Word document was saved. The browser window freezes for no reason. You can't hear anything from your speakers.

Data Handling Issues, Part I Doug Hennig

Advisor Answers. Match multiple items in a query. December, 2005 VFP 9/8/7

Client Side JavaScript and AJAX

Handling hierarchical data

Web Page Components Doug Hennig

6.170 Laboratory in Software Engineering Eclipse Reference for 6.170

A File Open Dialog Doug Hennig

Try Thor s Terrific Tools, Part 2

Advisor Discovery. Use BindEvent() to keep things in synch. BindEvent() Refresher. June, By Tamar E. Granor, technical editor

Speed in Object Creation and. Destruction. March 2016 Number 49. Tamar E. Granor, Ph.D.

The Ultimate Grid. Visual FoxPro 6 DORON FARBER. Structure of the Solution. Design Issues

From time to time Google changes the way it does things, and old tutorials may not apply to some new procedures.

PATTERN MAKING FOR THE PHOENIX HOOP

Data-Drive Your Applications Doug Hennig

New Program Update Sept 12, 2012 Build 187

Chris' Makefile Tutorial

Extending the VFP 9 IDE Doug Hennig

Preventing system crashes with Resource Meter

Integrating Visual FoxPro and MailChimp

Understanding Business Objects, Part 1

Android Manual Google Sync Contacts Not Working One Way

We Used to Do it That Way, but...

Building CircuitPython

HELPLINE. Dilwyn Jones


TiTiTo Manual. TiTiTo is a Tiny Timetabling Tool. Version 0.5 by Volker Dirr Preamble. Main Features.

Get Your Game On. Getting and Installing PCSX. Getting Plugins and BIOS. Installing the "Easy Stuff" Playing PlayStation Games in Linux

I Want To Wipe My Computer Clean And Start Over Windows 7

How To Manually Change Album Artwork On

In our first lecture on sets and set theory, we introduced a bunch of new symbols and terminology.

Update Manual Ios 7.1 Iphone 4s Wont >>>CLICK HERE<<<

C - Colour Mixing. Let's use the Sparkle module and some switches to make a colour mixer! 2018 courses.techcamp.org.

CPSC 320 Sample Solution, Playing with Graphs!

Rendering 17 Mixed Lighting

How To Stop Avg Search Appearing In New Tabs On Google Chrome

Working with the Dope Sheet Editor to speed up animation and reverse time.

What Does Manually Manage Music And Videos Mean On Iphone

IntelliSense at Runtime Doug Hennig

Manual Script Windows Batch If Condition. Syntax >>>CLICK HERE<<<

Fix, Speed Up, And Protect Your Computer In One Hour: Windows 7 / Windows Vista Edition By Nabeel Alzahrani

A New Beginning Doug Hennig

Google Groups. Using, joining, creating, and sharing. content with groups. What's Google Groups? About Google Groups and Google Contacts

File systems, databases, cloud storage

Developing Online Databases and Serving Biological Research Data

Using Visual Studio.NET: IntelliSense and Debugging

Manual Format Flash Drive Mac Os X Lion Startup

Consolidate data from a field into a list

Linked Lists. What is a Linked List?

Constraint Satisfaction Problems: A Deeper Look

Change Schema Active Directory Password Mac Users Can't

KMyMoney Transaction Matcher

How to Install Ubuntu on VirtualBox

Configuring Ubuntu to Code for the OmniFlash or OmniEP

1/29/2019. Storage Media. Storage Media

CATCH Me if You Can Doug Hennig

Windows 7 Ultimate Manual Update Full Version

How To Add Songs From Itunes To Iphone 5. Without Syncing >>>CLICK HERE<<<

mid=81#15143

Can't Delete Document From Print Queue Windows 8

JUnit Test Patterns in Rational XDE

How to configure DBxtra to use Internet Information Services on Windows Server 2012

FrontPage Help Center. Topic: FrontPage Basics

Using Windows Explorer and Libraries in Windows 7

An Illustrated Guide to Shell Magic: Standard I/O & Redirection

- In light of so many reports of USB sticks failing on the C64 mini, I thought I'd try test out some of Camcam's collection.

9.0 Help for End Users Release Notes Using Jive for Outlook...5

The Crypt Keeper Cemetery Software Online Version Tutorials To print this information, right-click on the contents and choose the 'Print' option.

Notes By: Shailesh Bdr. Pandey, TA, Computer Engineering Department, Nepal Engineering College

Install ADB on Windows

NETWORK THE HOME 10 FOLDERS APPS

Combos and Lists - The Forgotten Controls

Formal Methods of Software Design, Eric Hehner, segment 1 page 1 out of 5

SourceGen Project. Daniel Hoberecht Michael Lapp Kenneth Melby III

Transcription:

May, 2007 Advisor Answers Clean up a Project Visual FoxPro 9/8/7 Q: I've just inherited a VFP application for maintenance. Both the project itself and the project directories seem to contain a lot of files that aren't actually used in the application. How can I clean up so I know what I'm working with? A: This is a common situation with projects that have been around for a while. Code gets replaced, test programs are written and left around, and so forth. Fortunately, it's fairly easy to clean up in most cases. The first step is to create a new project (CREATE PROJECT NewApp) and add the main program for the application to it. Then click on the Build button and choose Rebuild project. That pulls into the project all the files used by the main program and the programs it calls (recursively to the bottom of the chain). There is one caveat, which is that files referenced only indirectly (by macro expansion or name substitution) aren't pulled into the project. So you have to test carefully to make sure you haven't missed any files. You can use some code to help figure out whether you've omitted any files of importance. The following code builds a cursor of all the files found in one project that aren't found in another. Pass the project names, including paths, as parameters. LPARAMETERS coldproject, cnewproject LOCAL oold as VisualFoxpro.IFoxProject, ; onew as VisualFoxpro.IFoxProject MODIFY PROJECT (m.coldproject) NOWAIT oold = _VFP.ActiveProject MODIFY PROJECT (m.cnewproject) NOWAIT onew = _VFP.ActiveProject CREATE CURSOR Missing (mfile M) LOCAL ofile, onewfile, cfilename FOR EACH ofile IN oold.files * Look for each file from the old project * in the new project. The filename without path * is the key in the collection. cfilename = JUSTFNAME(oFile.Name) TRY onewfile = onew.files[m.cfilename]

CATCH * Used in old, not in new INSERT INTO Missing VALUES (ofile.name) ENDTRY This code uses the Project object and its Files collection. Whenever a VFP project is opened, a Project object is created. You can address the active project using _VFP.ActiveProject. To get the whole set of open projects, use the collection _VFP.Projects. The Project object has a Files collection containing all the files in the project. Each file in the collection has a key which is the file name without path (stem plus extension). The code here grabs a file from one project and tries to access the file with the same key in the other project. The use of TRY-CATCH eliminates a large brute force loop. When this program is done, the cursor Missing contains a list of all files in the old project that aren't in the new one. Once you've created a new project, the next step is to move the project and its code into a new directory, keeping only the code that's actually used. There are two ways to approach this task; both address the project as an object. The first approach is to run code to copy all the files referenced in a project into a new folder structure. The following code accepts the name (including path) of the project, the original path and the new path. It then opens the project and reads the list of files. For each, if a same-named file doesn't already exist in the new folder hierarchy, the file is copied. Folders are created as needed. For those VFP components that involve two files (forms, class libraries, and menus here), the memo file is also copied. (This code doesn't address memo files for reports and labels because the project for which it was written didn't include any.) Once this code has finished, you can copy the new project into the new folder and rebuild it. LPARAMETERS cproject, coriginalpath, cnewpath LOCAL oproject, ofile, cnewname, cnewfilepath MODIFY PROJECT (cproject) nowait oproject = _vfp.activeproject * Copy all files to appropriate directories FOR EACH ofile IN oproject.files cnewname = cnewpath + STREXTRACT(oFile.Name, ; coriginalpath,"",1,3) cnewfilepath = JUSTPATH(cNewName) IF NOT FILE(cNewName)

IF NOT DIRECTORY(cNewFilePath) MD (cnewfilepath) COPY FILE (ofile.name) TO (cnewname) IF JUSTEXT(cNewName) = "scx" AND ; NOT FILE(FORCEEXT(cNewName, "SCT")) COPY FILE (FORCEEXT(oFile.Name, "SCT")) TO ; (FORCEEXT(cNewName, "SCT")) IF JUSTEXT(cNewName) = "vcx" AND ; NOT FILE(FORCEEXT(cNewName, "VCT")) COPY FILE (FORCEEXT(oFile.Name, "VCT")) TO ; (FORCEEXT(cNewName, "VCT")) IF JUSTEXT(cNewName) = "mnx" AND ; NOT FILE(FORCEEXT(cNewName, "MNT")) COPY FILE (FORCEEXT(oFile.Name, "MNT")) TO ; (FORCEEXT(cNewName, "MNT")) The second approach is to copy everything to the new folders and then eliminate those that are not used in the project. The following code builds a list of suspect files. It accepts the name, including path of a project, and a list of folders to check. It first builds an array listing all the files in the project. Then, it goes through all the directories listed in the second parameter; in each, it checks every file against the list of files in the project. If the file isn't in the project, it adds it to a cursor. When this code is done, you can check the cursor and decide which files to delete. LPARAMETERS cproject, cpath * Look for unused code LOCAL oproject, ncounter, ofile LOCAL ndirs, ndir, adirs[1] MODIFY PROJECT (m.cproject) nowait oproject = _VFP.ActiveProject * First, make a list of all files in project LOCAL aprojfiles[oproject.files.count] ncounter = 0 FOR EACH ofile IN oproject.files ncounter = m.ncounter + 1 aprojfiles[m.ncounter] = UPPER(oFile.Name) CREATE CURSOR Unused (mfilename M) * Now traverse directories * First, make a list of directories ndirs = ALINES(aDirs, m.cpath, 1, ";", ",") CREATE CURSOR DirsToCheck (mdirname M) FOR ndir = 1 TO m.ndirs INSERT INTO DirsToCheck VALUES (adirs[m.ndir])

LOCAL afiles[1], colddir, cfile, nfilestocheck, cext colddir = SET("Default") + CURDIR() SCAN IF DIRECTORY(mDirName) CD ALLTRIM(mDirName) nfilestocheck = ADIR(aFiles, "*.*") FOR nfile = 1 TO m.nfilestocheck cfile = afiles[m.nfile, 1] cext = JUSTEXT(m.cFile) IF INLIST(cExt, "PRG", "SCX", "MNX", ; "FRX", "VCX", "QPR") IF ASCAN(aProjFiles, FORCEPATH(m.cFile, ; ALLTRIM(mDirName)), -1, -1, 1, 7) = 0 INSERT INTO Unused ; VALUES (FORCEPATH(m.cFile, ; DirsToCheck.mDirName)) ENDSCAN CD (m.colddir) RETURN This month's Professional Resource CD contain all three programs above, as ListMissingFiles.PRG, CopyProject.PRG, and CheckForUnusedCode.PRG, respectively. Cleaning away years of accumulation can help a lot when you start working with an existing project. Having a new folder structure and a project containing only code that's actually used makes it easier for you to figure out how the code works and what needs to be done. Tamar Find Out Where a Class is Used VFP 9/8 Q: I want to find all the places in a project where I've used a particular class. Is there an easy way to do this? Dmitry Litvak (via the Internet) A: My first instinct was to send you to Code References. This tool, introduced in VFP 8, searches a project or folder structure for a specified string and shows you all the places it's found. I use it extensively, especially when working with other people's code.

However, it turns out that Code References doesn't check the class of items it encounters in a form or class. It looks at the properties and methods and at the name of the object, but not the class or class library. Because the source code for Code References is provided with VFP (in the Tools\XSource\VFPTools\FoxRef folder-unzip Tools\XSource\XSource.Zip if you haven't already done so), you can modify the tool to check the class and/or class library. This change turns out to be remarkably easy. To search the class name, just add the following code to the DoSearch method of RefSearchForm in FoxRefSearch_Form.PRG: IF!EMPTY(Class) m.lsuccess = THIS.FindInText(Class, FINDTYPE_NAME, ; NVL(cRootClass, cclassname), cobjname, ; SEARCHTYPE_EXPR, UniqueID, "CLASS",.T.) The code goes after the block it's based on, which checks the object name (ObjName). Be aware that this code doesn't let you change the class name using Code References, but that's a good thing, since such changes have major consequences. (To change the name of a class, use the Class Browser and make sure everything that references that class is open in the Browser at the same time.) To search the class library, as well, add another analogous block that passes the ClassLoc field to FindInText. To use the updated tool, rebuild the Code References application and set _FoxRef to point to your new APP file. An updated version of FoxRefSearch_Form.PRG that searches in the Class field is included on this month's Professional Resource CD. If changing the tool makes you uncomfortable, you can write your own code to do the search instead. You can use the project object and its Files collection, like this: LPARAMETERS cproject, csearchclass LOCAL ofile, cupperclass MODIFY PROJECT (cproject) NOWAIT cupperclass = UPPER(m.cSearchClass) CREATE CURSOR Matches ; (mfilename M, nrecord N, mobjname M) FOR EACH ofile IN _VFP.ActiveProject.Files * If it's a form or classlib IF INLIST(oFile.Type, "K", "V") * Open the file and search SELECT 0

USE (ofile.name) ALIAS CXFile SCAN FOR UPPER(Class) == m.cupperclass * If inside loop, found a match. Save it. INSERT INTO Matches ; VALUES (ofile.name, RECNO(" CXFile"), ; CXFile.ObjName) ENDSCAN USE IN SELECT(" CXFile") RETURN When this code finishes, the cursor Matches contains a list of objects in the project that use the specified class. Each record in the cursor indicates the file, the object name and the record number in the file. The code uses a mixed approach, treating the project as an object, but treating the individual forms and class libraries as tables. It opens the project and traverses the Files collection. When it encounters a form (type "K") or a class library (type "V"), it opens the SCX or VCX as a table and loops through the records. This program is included on this month's PRD as SearchForClass.PRG. The two approaches to this problem highlight two of VFP's strengths. Having source code for so many of the tools that come with the product means we can tweak them when we need to. The open architecture that lets us write code to process projects and their files means we can supplement the provided tools with our own. Tamar