Search and Replace Component Property

Dear Experts

I've write a delphi application about 2 years, using a lot of TQuery and now I want to change width of table field, in example 10 to 30.

How can I replace all TQuery field property to match the new database field width ?

Is there any tools available ? i try to use GEReplace, it's very nice tools, but it can't solve my problem.

Best Regards
Adeng
LVL 1
adengAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Lee_NoverCommented:
well notepad would be a great tool for this :)
ofcourse if you have your forms in Text format not in Binary

the form as text looks like :

object Form1: TForm1
  Left = 192
  Top = 107
  Width = 870
  Height = 600
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Query1: TQuery
    Left = 160
    Top = 88
    object Query1xxx: TStringField
      FieldName = 'xxx'
      Size = 10
    end
  end
end


so what you do is simply find all of the TStringField entries and replace the Size value
you could create an app to do this for you but this method is also fast :)
0
adengAuthor Commented:
ya I agree with you, but the problem is *.dfm in binary format, and there's about 200 dfm file. It take alot of time to do it manually.

I can't use simple search and replace procedure, like search Size = 10 and replace it to Size = 35, because there's alot of posilibity other table field that has size 10.

I need tools, to search more than 1 line of code like :
  FieldName = 'xxx'
  Size = 10

and replace it to :
  FieldName = 'xxx'
  Size = 35

So only 'xxx' field will changed.

btw, thanks.

Regards
Adeng
0
TOndrejCommented:
You can use regular expressions in search/replace.
0
Rowby Goren Makes an Impact on Screen and Online

Learn about longtime user Rowby Goren and his great contributions to the site. We explore his method for posing questions that are likely to yield a solution, and take a look at how his career transformed from a Hollywood writer to a website entrepreneur.

TOndrejCommented:
What version of Delphi are you using?
0
Lee_NoverCommented:
that's what I meant, and also wrote :)
> search for all the TStringField and replace the Size value <


another option would be to make an expert
in the expert you simply do:
for I:=0 to ComponentCount-1 do
  if Components[I] is TStringField then
    TStringField(Components[I]).Size:=30;

for help on experts check out GExperts @ www.gexperts.org
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
TOndrejCommented:
> that's what I meant, and also wrote :)
What are you referring to?

> another option would be to make an expert
I'm writing the expert, I'll post it here when it's ready.
0
Lee_NoverCommented:
that's what I meant, and also wrote :) ->
> search for all the TStringField and replace the Size value <

the line above in qwazy comments :)



about the expert
will it have settings like :

Component Type: TComponent descendant;
Range: All comps, Selected comps;
Property: the PropertyName;
Value: NewValue for the property;

I wanted to write it myself but no time for it :)
0
TOndrejCommented:
It has an input dialog where you can specify:

component class (exact or including descendants)
property names and values to match
target property name
target property value

It will enumerate all modules in the active project, changing the matching components.

I don't see much sense in having a "Selected comps" option since you can already do that with the Object Inspector (and you can only select components on one form at a time).

Here's the code, although not thoroughly tested. Delphi 6 required; sorry, I don't keep earlier versions anymore.

PropChangeWizard.pas:

unit PropChangeWizard;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, ValEdit;

type
  TFormPropChange = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ComboBox1: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    ComboBox2: TComboBox;
    CheckBox1: TCheckBox;
    ValueListEditor1: TValueListEditor;
    Label3: TLabel;
    Label4: TLabel;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
    procedure ComboBox2Change(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure ValueListEditor1SetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
    procedure Edit1Change(Sender: TObject);
  private
    procedure ValidateInput;
  public
  end;

procedure Register;

implementation

uses
  ToolsAPI, TypInfo;

{$R *.dfm}

function ShowPropChangeDlg(var AClassName, APropName, AValue: string; var IncludeDescendants: Boolean;
  SearchProps: TStrings): TModalResult;
begin
  with TFormPropChange.Create(nil) do
    try
      Result := ShowModal;
      if Result = mrOK then
      begin
        AClassName := ComboBox1.Text;
        APropName := ComboBox2.Text;
        AValue := Edit1.Text;
        IncludeDescendants := CheckBox1.Checked;
        SearchProps.Text := ValueListEditor1.Strings.Text;
      end;
    finally
      Free;
    end;
end;

type
  TPropertyChangeWizard = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
  private
    FFormName: string;
    FMatches: TStringList;

    { IOTAWizard }
    function GetIDString: string;
    function GetName: string;
    function GetState: TWizardState;
    procedure Execute;
    { IOTAMenuWizard }
    function GetMenuText: string;

    function ChangeProperty(Component: IOTAComponent; const AClassName, APropName, AValue: string;
      IncludeDescendants: Boolean; SearchProps: TStrings): Boolean;
    function FindActiveProject: IOTAProject;
  public
    constructor Create;
    destructor Destroy; override;
  end;

function TPropertyChangeWizard.GetIDString: string;
begin
  Result := 'TOndrej.PropertyChange';
end;

function TPropertyChangeWizard.GetName: string;
begin
  Result := 'Property Change Wizard';
end;

function TPropertyChangeWizard.GetState: TWizardState;
begin
  Result := [wsEnabled];
end;

procedure TPropertyChangeWizard.Execute;
var
  AClassName, APropName, AValue: string;
  IncludeDescendants: Boolean;
  SearchProps: TStringList;
  I, J: Integer;
  Project: IOTAProject;
  Module: IOTAModule;
  FormEditor: IOTAFormEditor;
  Root: IOTAComponent;
begin
  FMatches.Clear;
  SearchProps := TStringList.Create;
  try
    if ShowPropChangeDlg(AClassName, APropName, AValue, IncludeDescendants, SearchProps) = mrOK then
    begin
      Project := FindActiveProject;
      if not Assigned(Project) then
        Exit;

      for I := 0 to Project.GetModuleCount - 1 do
      begin
        with Project.GetModule(I) do
        begin
          FFormName := FormName;
          if FormName = '' then
            Module := nil
          else
            Module := OpenModule;
          if Assigned(Module) then
          begin
            FormEditor := nil;
            for J := 0 to Module.ModuleFileCount - 1 do
              if Supports(Module.ModuleFileEditors[J], IOTAFormEditor, FormEditor) then
              begin
                Root := FormEditor.GetRootComponent;
                FormEditor := nil;
                if ChangeProperty(Root, AClassName, APropName, AValue, IncludeDescendants, SearchProps) then
                  Module.MarkModified;
                Root := nil;

                Break;
              end;
          end;
          Module := nil;
          FFormName := '';
        end;
      end;

      if FMatches.Count > 0 then
        ShowMessage('Affected component(s):'#13#10#13#10 + FMatches.Text);
    end;
  finally
    SearchProps.Free;
  end;
end;

function TPropertyChangeWizard.GetMenuText: string;
begin
  Result := 'Change properties';
end;

function TPropertyChangeWizard.ChangeProperty(Component: IOTAComponent; const AClassName, APropName, AValue: string;
  IncludeDescendants: Boolean; SearchProps: TStrings): Boolean;
var
  I: Integer;
  C1, C2: TPersistentClass;
  Instance: TComponent;
  PropInfo: PPropInfo;
  Match: Boolean;
begin
  Result := False;
  if not Assigned(Component) then
    Exit;

  Instance := TComponent(Component.GetComponentHandle);
  C1 := GetClass(AClassName);
  C2 := TPersistentClass(Instance.ClassType);
  if not Assigned(C1) or not Assigned(C2) then
    Exit;
  if (C1 = C2) or (IncludeDescendants and C2.InheritsFrom(C1)) then
  begin
    Match := True;
    for I := 0 to SearchProps.Count - 1 do
      if SearchProps.Names[I] <> '' then
      begin
        PropInfo := GetPropInfo(C2, SearchProps.Names[I]);
        if not Assigned(PropInfo) then
        begin
          Match := False;
          Break;
        end;
        with SearchProps do
          if GetPropValue(Instance, Names[I], True) <> Values[Names[I]] then
          begin
            Match := False;
            Break;
          end;
      end;
    if Match then
    begin
      PropInfo := GetPropInfo(C2, APropName);
      if Assigned(PropInfo) then
      begin
        SetPropValue(Instance, APropName, AValue);
        FMatches.Add(Format('%s.%s [%s]', [FFormName, Instance.GetNamePath, Instance.ClassName]));
        Result := True;
      end;
    end;
  end;
  for I := 0 to Component.GetComponentCount - 1 do
    Result := Result or ChangeProperty(Component.GetComponent(I), AClassName, APropName, AValue, IncludeDescendants,
      SearchProps);
end;

function TPropertyChangeWizard.FindActiveProject: IOTAProject;
var
  ProjectGroup: IOTAProjectGroup;
  I: Integer;
begin
  Result := nil;
  ProjectGroup := nil;
  with BorlandIDEServices as IOTAModuleServices do
    for I := 0 to ModuleCount - 1 do
      if Supports(Modules[I], IOTAProjectGroup, ProjectGroup) then
        Break;
  if Assigned(ProjectGroup) then
    Result := ProjectGroup.ActiveProject
  else
  begin
    Result := nil;
    with BorlandIDEServices as IOTAModuleServices do
      for I := 0 to ModuleCount - 1 do
        if Supports(Modules[I], IOTAProject, Result) then
          Break;
  end;
end;

constructor TPropertyChangeWizard.Create;
begin
  inherited Create;
  FMatches := TStringList.Create;
end;

destructor TPropertyChangeWizard.Destroy;
begin
  FMatches.Free;
  inherited Destroy;
end;

procedure TFormPropChange.ValidateInput;
var
  C: TPersistentClass;
begin
  C := GetClass(ComboBox1.Text);
  Button1.Enabled := Assigned(C) and (Assigned(GetPropInfo(C, ComboBox2.Text)) or CheckBox1.Checked);
end;

procedure TFormPropChange.FormCreate(Sender: TObject);
var
  I, J: Integer;
begin
  with Constraints do
  begin
    MinHeight := Height;
    MinWidth := Width;
  end;
  with BorlandIDEServices as IOTAPackageServices do
    for I := 0 to PackageCount - 1 do
      for J := 0 to ComponentCount[I] - 1 do
        ComboBox1.Items.Add(ComponentNames[I, J]);
end;

procedure TFormPropChange.ComboBox1Change(Sender: TObject);
var
  C: TPersistentClass;
  PropList: PPropList;
  I: Integer;
begin
  with ComboBox2 do
  begin
    Items.BeginUpdate;
    try
      Clear;
      with Sender as TComboBox do
        C := GetClass(Text);
      if Assigned(C) then
        for I := 0 to GetPropList(C.ClassInfo, PropList) - 1 do
          Items.Add(PropList^[I]^.Name);
    finally
      Items.EndUpdate;
    end;
  end;
  ValidateInput;
end;

procedure TFormPropChange.ComboBox2Change(Sender: TObject);
begin
  ValidateInput;
end;

procedure TFormPropChange.CheckBox1Click(Sender: TObject);
begin
  ValidateInput;
end;

procedure TFormPropChange.ValueListEditor1SetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
begin
  ValidateInput;
end;

procedure TFormPropChange.Edit1Change(Sender: TObject);
begin
  ValidateInput;
end;

procedure Register;
begin
  RegisterPackageWizard(TPropertyChangeWizard.Create);
end;

end.

PropChangeWizard.dfm:

object FormPropChange: TFormPropChange
  Left = 262
  Top = 107
  Width = 333
  Height = 308
  Caption = 'Change properties'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poDesktopCenter
  OnCreate = FormCreate
  DesignSize = (
    325
    281)
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 8
    Top = 8
    Width = 29
    Height = 13
    Caption = '&Class:'
    FocusControl = Button1
  end
  object Label2: TLabel
    Left = 8
    Top = 184
    Width = 86
    Height = 13
    Anchors = [akLeft, akBottom]
    Caption = 'Change &Property:'
    FocusControl = ComboBox2
  end
  object Label3: TLabel
    Left = 8
    Top = 56
    Width = 120
    Height = 13
    Caption = '&Search conditions (AND):'
    FocusControl = ValueListEditor1
  end
  object Label4: TLabel
    Left = 160
    Top = 184
    Width = 54
    Height = 13
    Anchors = [akLeft, akBottom]
    Caption = 'New &Value:'
    FocusControl = Edit1
  end
  object Button1: TButton
    Left = 160
    Top = 248
    Width = 75
    Height = 25
    Anchors = [akRight, akBottom]
    Caption = 'OK'
    Enabled = False
    ModalResult = 1
    TabOrder = 5
  end
  object Button2: TButton
    Left = 240
    Top = 248
    Width = 75
    Height = 25
    Anchors = [akRight, akBottom]
    Cancel = True
    Caption = 'Cancel'
    ModalResult = 2
    TabOrder = 6
  end
  object ComboBox1: TComboBox
    Left = 8
    Top = 24
    Width = 145
    Height = 21
    ItemHeight = 13
    Sorted = True
    TabOrder = 0
    OnChange = ComboBox1Change
  end
  object ComboBox2: TComboBox
    Left = 8
    Top = 200
    Width = 145
    Height = 21
    Anchors = [akLeft, akBottom]
    ItemHeight = 13
    Sorted = True
    TabOrder = 3
    OnChange = ComboBox2Change
  end
  object CheckBox1: TCheckBox
    Left = 160
    Top = 24
    Width = 129
    Height = 17
    Caption = 'Include &Descendants'
    TabOrder = 1
    OnClick = CheckBox1Click
  end
  object ValueListEditor1: TValueListEditor
    Left = 8
    Top = 72
    Width = 306
    Height = 104
    Anchors = [akLeft, akTop, akRight, akBottom]
    KeyOptions = [keyEdit, keyAdd, keyDelete, keyUnique]
    Strings.Strings = (
      '=')
    TabOrder = 2
    TitleCaptions.Strings = (
      'Property'
      'Value')
    OnSetEditText = ValueListEditor1SetEditText
    ColWidths = (
      150
      150)
  end
  object Edit1: TEdit
    Left = 160
    Top = 200
    Width = 153
    Height = 21
    Anchors = [akLeft, akBottom]
    TabOrder = 4
    OnChange = Edit1Change
  end
end

Installation:
Create a new designtime-only package, add this unit, add designide.dcp to the requires clause, compile and install the package.

Under 'Help' menu a new menu item 'Change properties' should appear. When you select it, a modal dialog should appear.
For your specific case, it seems you want to input the following in the dialog:

Class: TStringField
Include descendants: no (not necessary)
Search conditions: FieldName|xxx (only one condition needed)
Change Property: Size
New Value: 35

This will enumerate all modules within the currently active project and set Size property of all TStringField components whose FieldName = 'xxx' to 35.

HTH
TOndrej
0
adengAuthor Commented:
Wow what an expert you are, give me a day to learn and create your source code.

Best Regards
Adeng
0
adengAuthor Commented:
oops... i used Delphi 3.0 !
It will take to much time for me to convert my application to newer delphi version.

:(

Adeng
0
TOndrejCommented:
Perhaps someone could convert the expert to Delphi 3.
IIRC, D3 used the old-style OpenTools API.
As I've said, I don't have D3 anymore; sorry.
0
CleanupPingCommented:
adeng:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
Lukasz LachCommented:
adeng,
No comment has been added lately (17 days), so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area for this question:

RECOMMENDATION: split points between Lee_Nover http:#7108197 and TOndrej http:#7110344

Please leave any comments here within 7 days.

-- Please DO NOT accept this comment as an answer ! --

Thanks,

anAKiN
EE Cleanup Volunteer
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.