با سلام
من از گريد ehlib استفاده كردم.سه تا فيلد دارم كه مي خوام يكي از اونها از يك جدول خونده بشه . ولي وقتي برنامه اجرا مي شه دوتا ستون ديگه فعال نيست. بايد چكار كنم؟ لازمه بگم اطلاعات سه ستون در يك جدول ديگه ثبت مي شوند.
Printable View
با سلام
من از گريد ehlib استفاده كردم.سه تا فيلد دارم كه مي خوام يكي از اونها از يك جدول خونده بشه . ولي وقتي برنامه اجرا مي شه دوتا ستون ديگه فعال نيست. بايد چكار كنم؟ لازمه بگم اطلاعات سه ستون در يك جدول ديگه ثبت مي شوند.
سلام
خوب اگه میخوای فقط نمایش اطلاعات داشته باشی، اول یه Query بنویس که فیلدهای مورد نظرت یک جا ایجاد بشن. بعدا اون رو به گرید مرتبط کن.
دوست عزيز كاري كه گفتيد انجام دادم ولي بازم همون مشكل هست.فوريه.:متفکر:
اون کامپوننت از اسمش هم پیدا ست که برای نمایش داده های بانک هست. شما باید فیلدی در دیتاست داشته باشید که گرید بتونه نمایش بده. اگر کوئری شما فقط یک فیلد بر میگردونه، و مابقی اطلاعات را باید از جای دیگه ایی بخونید، باید برای دیتاستی که گرید بهش وصل هست، فیلدهای محاسباتی (Calculated Fields) ایجاد کنید، و خودتان در زمان اجرا به اون فیلدها مقدار بدید.
درباره ساخت اینگونه فیلدها قبلا توضیح داده شده.
فیلد محاسباتی قابل تغییر توسط کاربر نیست.
پس من بايد چيكار كنم؟
كامل توضيح ميدم. يه فرم دارم كه كاربر در فرم قبلي يك سري مشخصات مثل نام دستگاه رو تعيين مي كنه. با توجه به هر دستگاه، موارد كنترلي اون دستگاه از جدول پايه موارد چك كردن خونده مي شه كه در ستون اول نمايش داده مي شه. ستون دوم كه چك باكسه و ستون سوم براي توضيحات در نظر گرفته شده. دو تا ستون آخر در جدولمون نيست. كاربر موارد كنترلي دستگاه رو چك ميكنه و موارد درست رو تيك مي زنه و در يه جدول ديگه كه هر سه ستون جزو فيلدهاي اون هست ذخيره ميكنه.
حالا من بايد چكار كنم كه دو ستون آخر نيز فعال باشند؟:عصبانی++:
كسي نيست جواب منو بده. فكر مي كردم مي تونم مشكلمو اينجا حل كنم.:گریه:
سلام.
چه جوری این دو تا ستون رو به دی بی گرید اضافه کردی؟نقل قول:
دو تا ستون آخر در جدولمون نيست.
خاصیت dataSource مربوط به DBGrid رو چی تنظیم کردی؟
شما کوئری رو اینجوری بنویس که یک فیلد از جدول اول (به قول خودتون جدول پایه) و دو فیلد از جدول دوم برگردونه؛ نه اینکه فقط دو فیلد از جدول دوم select کنه. بعد از این کار DBGrid رو وصل کن به همین کوئری.
اینجوری مشکلت حل میشه.
بعد میتونی اطلاعات این کوئری رو در جدول دوم ذخیره کنی.
من از طريق join كردن دوتا جدول به فيلدهايي كه مي خواستم دسترسي پيدا كردم. همونطور كه مي دونيد join داراي قسمت on است كه من اونو روي يه فيلد مشترك گذاشتم. ولي چون جدول دوم خاليه. در نتيجه هيچ ركوردي برگردونده نميشه و گريد من خالي مي مونه در صورتي كه من ميخوام ستون اولم با جدول اولم پر بشه. كار ه ديگه اي نميشه كرد؟
از Union استفاده کنید.
واقعا ممنونم. تونستم با دستور union مشكلمو حل كنم. اما وقتي توي يه سطر يه چيزي مينويسم و يا چك باكسو تيك مي زنم و ميخوام برم يه سطر ديگه پيغام زير رو ميده.چرا؟
Row can not be located for updating . some values may have been changed since it was last read.
اگه از ADO استفاده می کنید، این کد مشکلتون رو حل می کنه:
ADOQuery1.Properties['Update Criteria'].Value := 0;
اره. از adoqouery استفاده مي كنم. دستور select رو تو onshow نوشتم. اين كد رو بايد كجا بذارم.
يه سوال ديگه :ركورد هاي dbgrideh رو چطوري بايد توي جدولم ذخيره كنم. لازمه بگم 3تا فيلد ديگه هم دارم كه بيرون gride و واسه همه ركوردها ثابته. ممنون.
منظورتون OnShow فرمه؟نقل قول:
دستور select رو تو onshow نوشتم
میتونی در رویداد AfterOpen بذاری.نقل قول:
اين كد رو بايد كجا بذارم.
از طریق خاصیت Fields میتونی بهشون دسترسی داشته باشی. مثلا میتونی اینطور بنویسی:نقل قول:
ركورد هاي dbgrideh رو چطوري بايد توي جدولم ذخيره كنم.
Table2.FieldByName('نام فیلد').Value := DBGridEH1.Fields[شماره فیلد].AsVariant;
ضمناً شماره فیلد دی بی گرید از صفر شروع میشه.
من تستش کردم. مشکلی نداره. احتمالا یه جایی از تنظیمات یا کد شما مشکل داره؛ بیشتر بررسی کنید.نقل قول:
من اون قطعه كد رو توي afteropen كوئري نوشتم اما بازم همون ارور رو ميده.
مقدار اولیه شمارنده حلقه رو چند دادید؟ مقدار نهایی اون رو هم چک کنید.نقل قول:
براي ذخيره يكباره تمام ركوردهاي گريد از for استفاده كردم اما خطاي out of index ميده. كار ديگه اي ميشه انجام داد؟
دقيق ميگم چيكار كردم. كد زير رو توي خاصيت sql كوئريم نوشتم تا بتونم فيلدهايي رو كه ميخوام به گريدم وصل كنم.
SELECT fc_check,fc_comment,TB_fanibaseCHK.control_item ,
TB_fanibaseCHK.check_period,oc_check,oc_comment,
TB_opratorbaseCHK.control_item ,TB_opratorbaseCHK.check_period
from TB_faniCHK,TB_fanibaseCHK,TB_opratorCHK,TB_oprator baseCHK
توي afteropen گريد كد ي كه شما گفتيد رو نوشتم.
ديتاسورس گريدمو به ديتاسورسي كه كوئريم به اون وصله وصل كردم.
براي اينكه ستون اول گريد رو پر كنم كد زير رو توي onshow فرمم گذاشتم.
with DataModule1.ADOQuery1 do
begin
SQL.Text:='select * from TB_set where set_name like'+QuotedStr(Edit3.Text);
Open;
end;
with DataModule1.ADOQuery3 do
begin
SQL.Text:='SELECT s_id,control_item,check_period,fc_date,fc_check,fc _comment from TB_faniCHK'+
' union '+
' select s_id,control_item as c1,check_period,null,null,null from TB_fanibaseCHK'+
' where s_id like '+QuotedStr(DataModule1.ADOQuery1.FieldValues['s_id'])+'and check_period like '+QuotedStr(Edit1.Text);
open;
end;
بله.نقل قول:
اون كد رو بايد براي كوئري بنويسم كه گريد بهش وصله ديگه؟
مگه DBGridEH خاصیت RecordCount داره؟نقل قول:
مقدار اوليه رو 1 و مقدار نهايي dbgirudeh1.recordcount -1 دادم.
فکر کنم مقدار اولیه رو باید صفر بدی.
راستی من حواسم نبود، شما به جای اینکه رکوردهای DBGrid رو در جدول دوم ذخیره کنی، رکوردهای همون کوئری رو ذخیره کن؛ اینطوری بهتره.
من فكر مي كنم شما متوجه مشكل نشديد.بايد ركورد گريد رو ذخيره كنم.چون كوئريم فقط شامل ستون اول گريد ميشه.ستون دوم و سوم رو كاربر بايد پر كنه و سپس توي جدول دوم ذخيره كنه.
dbgrideh خاصيت recordcount داره . for من چه ايرادي داره؟
لطفا بگید وظیفه ADOQuery1 و ADOQuery3 چیه؟ هر کدوم چکار می کنه؟نقل قول:
من فكر مي كنم شما متوجه مشكل نشديد.بايد ركورد گريد رو ذخيره كنم.چون كوئريم فقط شامل ستون اول گريد ميشه.ستون دوم و سوم رو كاربر بايد پر كنه و سپس توي جدول دوم ذخيره كنه.
شما DBGrid رو به کدوم یک از اینا وصل کردید؟
این دستور Select مال کدوم کوئریه؟نقل قول:
كد زير رو توي خاصيت sql كوئريم نوشتم تا بتونم فيلدهايي رو كه ميخوام به گريدم وصل كنم.
SELECT fc_check,fc_comment,TB_fanibaseCHK.control_item ,
TB_fanibaseCHK.check_period,oc_check,oc_comment,
TB_opratorbaseCHK.control_item ,TB_opratorbaseCHK.check_period
from TB_faniCHK,TB_fanibaseCHK,TB_opratorCHK,TB_oprator baseCHK
من تست کردم نداشت!نقل قول:
dbgrideh خاصيت recordcount داره .
دستور کاملش رو اینجا بنویس تا ببینیم می تونیم مشکلش رو حل کنیم یا نه؟نقل قول:
for من چه ايرادي داره؟
راستی یه بار هم گفتم، اگه سورس این قسمت از پروژه ات رو اینجا بزاری فکر کنم خیلی راحت تر بشه جواب داد.
براي جك كردن موارد كنترلي دستگاه هاي مختلف، كاربر توي يك فرم نام دستگاه، دوره زماني چك كردن و اسم خودشو انتخاب ميكنه و وارد فرم جديدي كه موارد كنترلي اون دستگاه رو با توجه به دوره از جدول پايه خونده ميشه و توي گريد نمايش داده ميشه.Adoquery1 براي پيدا كردن نام دستگاه از جدول دستگاههاست. Adoquery3 براي خوندن موارد كنترلي دستگاه از جدول پايه است. كه ديتاسورس گريد به adoquery3 وصله.
procedure TFanicheckFM.FormShow(Sender: TObject);
begin
Edit1.Text:=Check1FM.ComboBox1.Text;
Edit3.Text:=Check1FM.ComboBox3.Text;
Edit2.Text:=Check1FM.ComboBox2.Text;
with DataModule1.ADOQuery1 do
begin
SQL.Text:='select * from TB_set where set_name like'+QuotedStr(Edit3.Text);
Open;
end;
with DataModule1.ADOQuery3 do
begin
SQL.Text:='SELECT s_id,control_item,check_period,fc_date,fc_check,fc _comment from TB_faniCHK'+
' union '+
' select s_id,control_item,check_period,null,null,null from TB_fanibaseCHK'+
' where s_id like '+QuotedStr(DataModule1.ADOQuery1.FieldValues['s_id'])+'and check_period like '+QuotedStr(Edit1.Text);
open;
end;
end;
دستور زير رو براي دسترسي به فيلدهاي دوم و سوم گريد كه از جدولي خونده شدند كه قراره بعد از پر كردن فرم توي اون دخيره بشن،توي خاصيت sql كوئري 3 نوشتم.
SELECT fc_check,fc_comment,TB_fanibaseCHK.control_item ,
TB_fanibaseCHK.check_period,oc_check,oc_comment,
TB_opratorbaseCHK.control_item ,TB_opratorbaseCHK.check_period
from TB_faniCHK,TB_fanibaseCHK,TB_opratorCHK,TB_oprator baseCHK
دستور for :
procedure TFanicheckFM.Button1Click(Sender: TObject);
var i:integer;
begin
for I := 1 to DBGridEh1.RowCount - 1 do
begin
with DataModule1.ADOQuery2 do
begin
SQL.Text:='insert into TB_faniCHK (s_id,control_item,check_period,fc_date,fc_check,f c_comment,fani_name)'+
' values (' +IntToStr(DataModule1.ADOQuery1.FieldValues['s_id'])+','+
QuotedStr(Trim(DBGridEh1.Fields[0].AsVariant))+','+QuotedStr(Edit1.Text)+','+
QuotedStr(DBGridEh1.Columns[1].Title.Caption)+','+BoolToStr(DBGridEh1.Fields[1].AsBoolean)+','+
QuotedStr(Trim(DBGridEh1.Fields[2].AsVariant))+','+QuotedStr(Edit2.Text)+')';
ExecSQL;
end;
end;
end;
سلام.خواهش ميكنم يكي بگه من چيكار بايد بكنم؟ من فردا دفاعيه دارم و اين مشكلم هنوز برطرف نشده.خواهش مي كنم.:گریه::گریه::گریه:
دوست عزیز. چون اطلاعات کافی از پروژه ات ندارم نمی تونم مشکلت رو پیدا کنم. من نمی دونم شما چند جدول داری، چه فیلدهایی دارن و ... . توضیحاتی هم که دادی کافی نیست و یه کم هم گنگه.نقل قول:
خواهش ميكنم يكي بگه من چيكار بايد بكنم؟ من فردا دفاعيه دارم و اين مشكلم هنوز برطرف نشده.خواهش مي كنم
قبلا هم گفتم؛ برنامه ات رو اینجا آپلود کن تا ببینیم مشکلش چیه. انشالله تا شب درست میشه.
اگه میتونی همه رو بزار. دیتابیس رو هم بذار.نقل قول:
تمام برنامه رو بذارم يا فقط همون فرمي كه ايراد داره؟
خيلي سعي كردم همه رو بذارم.attach نشد.نقل قول:
اگه میتونی همه رو بزار. دیتابیس رو هم بذار.
check1UN فرميه كه كاربر نوع چك ليست رو انتخاب ميكنه.و وارد fanicheckUN ميشه. اسكريپت جدولام رو هم گذاشتم. ديتابيس رو هم نتونستم attach كنم. اميدوارم بدرد بخوره.
به خاطر كمكتون يك دنيا ممنون.
دو تا سوال دارم:
1- مگه DBGridEH شما به ADOQuery3 وصل نیست؟
2- مگه این سه تا ستونی که در DBGridEH شما هست، توسط همین ADOQuery3 از دو تا جدول بدست نمیاد؟
خیلی خوب. بنابراین شما به جای اینکه رکوردهای دی بی گرید رو در جدول دوم ذخیره کنی، رکوردهای همین ADOQuery3 رو ذخیره کن. این خیلی راحت تره. کدش رو فکر کنم خودت بتونی بنویسی.نقل قول:
آره.جواب دوتا سوالتون مثبته.
اگه مشکلی بود بگو. من امشب باز هم به این تاپیک سر میزنم.
راستی مشکل دستور for هم اینه که هیچ دستوری در حلقه ننوشتی که به رکورد بعدی بره و در هر بار اجرای حلقه رکورد اول رو ذخیره می کنه.
من اين كارو كردم ذخيره مي كنه.البته با كد قبلي هم ذخيره مي كرد.اما وقتي ميخوام از يه ركورد وارد يكي ديگه بشم همون خطاي row can not be located رو ميده.نقل قول:
خیلی خوب. بنابراین شما به جای اینکه رکوردهای دی بی گرید رو در جدول دوم ذخیره کنی، رکوردهای همین ADOQuery3 رو ذخیره کن. این خیلی راحت تره. کدش رو فکر کنم خودت بتونی بنویسی.
ميشه بگيد دستورش چيه؟نقل قول:
راستی مشکل دستور for هم اینه که هیچ دستوری در حلقه ننوشتی که به رکورد بعدی بره و در هر بار اجرای حلقه رکورد اول رو ذخیره می کنه.
كد من اينه:
for I := 1 to DataModule1.ADOQuery3.RecordCount - 1 do
begin
with DataModule1.ADOQuery2 do
begin
SQL.Text:='insert into TB_faniCHK (s_id,control_item,check_period,fc_date,fc_check,f c_comment,fani_name)'+
' values (' +IntToStr(DataModule1.ADOQuery1.FieldValues['s_id'])+','+
QuotedStr(DataModule1.ADOQuery3.FieldValues['control_item'])+','+QuotedStr(DataModule1.ADOQuery3.FieldValues['check_period'])+','+
QuotedStr(DBGridEh1.Columns[1].Title.Caption)+','+BoolToStr(DataModule1.ADOQuery 3.FieldByName('fc_check').AsBoolean)+','+
QuotedStr(DataModule1.ADOQuery3.FieldValues['fc_comment'])+','+QuotedStr(Edit2.Text)+')';
ExecSQL;
end;:خجالت:
یک نکته خارج از بحث: وقتی می خواید در پستتون کد بنویسید، اون رو داخل تگ کد بنویسید تا درست نمایش داده بشه.
و اما کد شما:
DataModule1.ADOQuery3.First;امیدوارم این کد مشکلتون رو حل کنه. البته من دستور اس کیو ال تون رو بررسی نکردم.
while not DataModule1.ADOQuery3.Eof do
begin
with DataModule1.ADOQuery2 do
begin
SQL.Text:='insert into TB_faniCHK (s_id,control_item,check_period,fc_date,fc_check,f c_comment,fani_name)'+
' values (' +IntToStr(DataModule1.ADOQuery1.FieldValues['s_id'])+','+
QuotedStr(DataModule1.ADOQuery3.FieldValues['control_item'])+','+QuotedStr(DataModule1.ADOQuery3.FieldValues['check_period'])+','+
QuotedStr(DBGridEh1.Columns[1].Title.Caption)+','+BoolToStr(DataModule1.ADOQuery 3.FieldByName('fc_check').AsBoolean)+','+
QuotedStr(DataModule1.ADOQuery3.FieldValues['fc_comment'])+','+QuotedStr(Edit2.Text)+')';
ExecSQL;
end;
Next;
end;
الان ديگه حتي وقتي دكمه ثبت رو هم مي زنم همون خطاي row can not رو ميدهنقل قول:
امیدوارم این کد مشکلتون رو حل کنه. البته من دستور اس کیو ال تون رو بررسی نکردم.
یه کار دیگه هم می تونید بکنید: برای ثبت، از دستورات sql استفاده نکنید؛ از همون دستور Insert و post جدول استفاده کنید.
اگه باز هم مشکلتون حل نشد سعی کنید کل پروژه تون رو آپلود کنید (سری قبل نمی دونم چرا نتونستید آپ کنید؟). انشالله درستش می کنیم.
برای درج یک رکورد در یک ADOTable، از دستور Insert استفاده میشه. یک کد نمونه:نقل قول:
متوجه منظورتون نميشم.ميشه توضيح بديد.من تا حالا اين كارو نكردم.
with ADOTable1 do
begin
Insert;
FieldByName('نام فیلد').Value := مقدار مورد نظر;
FieldByName('نام فیلد').Value := مقدار مورد نظر;
.
.
.
FieldByName('نام فیلد').Value := مقدار مورد نظر;
Post;
end;
من دو سه ساعت دیگه میام. سعی کنید پروژه تون رو بذارید.
سلام.بك آپ ديتابيس و برنامه رو گذاشتم. ولي فايل exe رو نشد بذارم.
username رو admin و password رو 1 وارد كنيد. واقعا ممنون.
sql ام 2000 و دلفي 2007
من الان پروژه تون رو دانلود کردم. دارم بررسی می کنم...
متاسفانه هر کاری کردم نتونستم sql server 2000 رو درست نصب کنم. نمی دونم چرا اذیت می کنه؛ معذرت. و بنابراین نتونستم برنامه رو تست کنم.
یه راه حل برای از بین بردن اون پیغام خطا(row can not):
خاصیت LockType همه ی جدولها و کوئری هاتون رو به ltPessimistic تغییر بدید. امیدوارم دیگه جواب بده.
یک نکته هم هست؛ اگه یه جدول یا کوئری فیلد کلید نداشته باشه و بخوایم یه رکوردش رو ویرایش یا حذف کنیم، باز هم اون پیغام خطا میاد.