Accountレコードに対して、精确查询、模糊查询を実現したいと思います。
精確検索というのは、完全に一致的なレコード名を入力しながら、検索いたします。
曖昧検索というのは、部分的なレコード名を入力しながら、検索いたします。SOQLのLIKE通りに、% Name % など。
最終的な画面イメージ
取引先名と種別も入力するって検索できる仕様、曖昧検索と精確検索ボタン、データクリアボタン
二つとも空でない、最低2文字を入力する、「%」は入力する場合、検索できず制限(SQLインジェクションを防ぐ)
曖昧検索:(取引先名も曖昧&&種別も曖昧、同時成立)
①何も入力しない
②「%」を含む
③1文字を入力する
④正常に入力する、レコードなし場合
⑤正常に入力する、レコードある場合
⑥「クリア」ボタンを押下する
精確検索:(取引先名と種別とも当てる場合)
①何も入力しない
②1文字を入力する
③正常に入力する、レコードなし場合
④正常に入力する、レコードある場合
⑤「クリア」ボタンを押下する(精確検索の⑥と同じ)
Visualforce1.vfp
<apex:page controller="Apex1" showHeader="false">
<script>
function doDeleteJs(accid) {
if (window.confirm("削除してよろしいでしょうか。")) {
doDeleteFn(accid);
}
}
function doEditJs(accid) {
var uuu="./EditAccountList_PAGE?core.apexpages.request.devconsole=1&Id="+accid;
window.location.href =uuu;
}
</script>
<style type="text/css">
/* footer右へ表示*/
.footer{
text-align: right;
}
</style>
<apex:sectionHeader subtitle="Account表示一覧" title="Account"/>
<!-- <apex:include pageName="NewAccountList_PAGE"/> -->
<!-- <apex:include pageName="AddAccountPage"/> -->
<apex:form id="formId2">
<apex:pageMessages id="message2"/>
<apex:pageBlock title="Add Account">
<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!save}" reRender="pageBlockTable,ttttt,formId2" />
<apex:commandButton value="Cancel" action="{!cancel}" reRender="pageBlockTable,formId2,pb2" />
</apex:pageBlockButtons>
<apex:pageBlockSection title="Account Details" columns="1" id="pb2">
<apex:inputField value="{!act.name}" />
<apex:inputField value="{!act.Type}"/>
<apex:inputField value="{!act.Industry}"/>
<apex:inputField value="{!act.Phone}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
<apex:form id="formId">
<apex:pageMessages id="message"/>
<apex:actionFunction name="doDeleteFn" action="{!doDelete}" reRender="formId" >
<apex:param name="id" value="" />
</apex:actionFunction>
<apex:pageBlock >
<apex:outputText value="検索条件: " > </apex:outputText>
<br/><br/>
<apex:inputText value="{!strCondName}" id="in">取引先名:</apex:inputText>
<apex:inputText value="{!strCondType}" id="ou">種別:</apex:inputText>
<br/> <br/>
<apex:commandButton value="曖昧検索" action="{!search}" reRender="formId,in,qqq,ppp,ooo,ou"/>
<apex:commandButton value="精確検索" action="{!exactSearch}" reRender="formId,in,qqq,ppp,ooo,ou"/>
<apex:commandButton value="クリア" action="{!clear}" reRender="formId,in,qqq,ppp,ooo,ou" />
</apex:pageBlock>
<apex:pageBlock title="検索結果(共{!count_size}レコード)" rendered="{!resultFlag}" id="qqq">
<apex:pageblockTable value="{!accResult}" var="a" id="ppp">
<apex:column value="{!a.Name}" />
<apex:column value="{!a.Type}" />
<apex:column value="{!a.Industry}" />
<apex:column value="{!a.Phone}" />
</apex:pageblockTable>
</apex:pageBlock>
<apex:pageBlock >
<apex:outputPanel id="showpanel">
<apex:pageBlockTable value="{!accounts}" var="acc" footerClass="footer" id="pageBlockTable">
<apex:column headerValue="Action" width="70px">
<apex:commandLink value="" onclick="doEditJs('{!acc.Id}');" style="color:#015ba7;" id="edit" reRender="formId,message,showpanel,buttons,pageBlockTable,foo">
Edit
</apex:commandLink>
|
<apex:commandLink value="" onclick="doDeleteJs('{!acc.Id}');" style="color:#015ba7;" id="del" reRender="formId,message,showpanel,buttons,pageBlockTable,foo">
Del
</apex:commandLink>
</apex:column>
<apex:column headerValue="取引先名" >
<apex:outputlink value="https://ap2.salesforce.com/{!acc.id}" target="_blank" >{!acc.Name}</apex:outputlink>
</apex:column>
<apex:column value="{!acc.Type}" />
<apex:column value="{!acc.Industry}" />
<apex:column value="{!acc.Phone}" />
</apex:pageBlockTable>
</apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>
説明:
①<apex:inputText value=”{!strCondName}” id=”in”>取引先名:</apex:inputText>
{!strCondName}:画面からの取引先名、取引先名の入力欄。
②<apex:commandButton value=”曖昧検索” action=”{!search}” reRender=”formId,in,qqq,ppp,ooo,ou”/>
Apexの「{!search}」メソッド名、検索処理。
③<apex:commandButton value=”クリア” action=”{!clear}” reRender=”formId,in,qqq,ppp,ooo,ou” />
Apexの「{!clear}」メソッド名、レコードと入力する値もクリア処理。
④<apex:pageBlock title=”検索結果(共{!count_size}レコード)” rendered=”{!resultFlag}” id=”qqq”>
「{!count_size}」メソッド名、レコード総数を取得。
rendered=”{!resultFlag}”:この<apex:pageBlock>が表示されるかどうかの制限、True:表示、False:非表示
https://developer.salesforce.com/docs/atlas.ja-jp.pages.meta/pages/pages_compref_pageBlock.htm
コンポーネントをページに表示するかどうかを指定する boolean 値。指定されていない場合、この値はデフォルトの true に設定されます。
Apex1.apxc
public with sharing class Apex1 {
public List<Account> accounts; //Account情報
public Account act{get;set;} //新規Account情報用
public list<Account> accResult {get;set;} //検索結果
public string strCondName {get;set;} //検索取引先名
public string strCondType {get;set;} //検索種別
public boolean resultFlag {get;set;} //検索結果表示フラグ
public Integer count_size; //検索レコードの総数
//画面に検索レコードの総数を返す
public Integer getCount_size() {
return count_size;
}
//コンストラクター
public Apex1() {
act = new Account(); //デフォルト New Accountオブジェクト
resultFlag = false; //デフォルト 検索結果一覧非表示
}
//変数 accounts のgetメソッド
public List<Account> getAccounts() {
try {
accounts= [select Id,Name,Type,Industry,phone from Account order by createddate desc limit 50 ];
return accounts;
} catch (Exception e) {
ApexPages.addMessages(e);
return null;
}
}
//精確検索
public void exactSearch(){
List<Account> exactSearchSOQL;
exactSearchSOQL = [select name,id,Type,Industry,phone from Account where name=:strCondName and type=:strCondType limit 100];
//入力した取引先名と種別との条件 判断 空でない && サイズ2を超える
if(!String.isBlank(strCondName) && !String.isBlank(strCondType) && strCondName.length()>=2 && strCondType.length()>=2){
if(exactSearchSOQL.size()!=0 ){
//検索結果一覧表示
resultFlag = true;
accResult = exactSearchSOQL;
//検索レコードの総数を取得
count_size = [select count() from Account where name like:strCondName and type like:strCondType limit 100];
}else {
//system.debug('123=='+exactSearchSOQL);
//検索するレコード存在しない
resultFlag = false;
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索条件に該当するデータがありません!'));
}
} else{
//system.debug('yyyyy='+strCondName);
//一つ空の場合
if(String.isBlank(strCondName)|| String.isBlank(strCondType) ){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '【取引先名】と【種別】を入力してください !'));
return;
}
//一つサイズ 2を超えない場合、および データベースと同じレコード名
if(strCondName.length()<2 || strCondType.length()<2){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索語には【取引先名】と【種別 】各2 文字以上を指定する必要があります!'));
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索条件は完全に等しい【取引先名】と等しい【種別】を入力してください!'));
}
}
}
//曖昧検索
public void search(){
// flag = false;
//String strCondName2 = ApexPages.currentPage().getParameters().get('strCondName');
//system.debug('99999='+strCondName);
//if(strCondName!=null || !strCondName.equals('') || strCondName!=''){
//system.debug('qqqqq='+strCondName);
//sql injection 1' or '1' = '1';-- %
//string searchQuery='select name,id,Type,Industry,phone from Account where name like \'%'+strCondName+'%\' Limit 100';
//strCondName = strCondName;
List<Account> searchSOQL;
//曖昧検索 定義
String searchName ='%'+strCondName+'%';
String searchType ='%'+strCondType+'%';
// String searchName2 = ''+ strCondName+ '';
searchSOQL = [select name,id,Type,Industry,phone from Account where name like:searchName and type like:searchType limit 100];
//system.debug('232323==='+searchSOQL);
//考えるプロセス
//String soql = 'select name,id,Type,Industry,phone from Account where name like \'%%\' Limit 100';
//SQLインジェクション=SQL Injection 対策
//String soql = 'select name,id,Type,Industry,phone from Account where name like'+'\''+ string.escapeSingleQuotes('%'+strCondName+'%')+'\'';
//system.debug('aaaaa='+soql);
//system.debug('bbbbb='+strCondName);
//system.debug(strCondName.containsAny('%'));
//system.debug('length==='+strCondName.length());
//入力した取引先名と種別との条件 判断 空でない && %を含まない && サイズ2を超える
if((!String.isBlank(strCondName) && !strCondName.containsAny('%') && strCondName.length()>=2) && (!String.isBlank(strCondType) && !strCondType.containsAny('%')&& strCondType.length()>=2)){
//if(searchQuery!=soql){
//system.debug('6666='+strCondName);
//if(Database.query(soql).size()!=0){
if(searchSOQL.size()!=0){
//検索結果一覧表示
resultFlag = true;
accResult = searchSOQL;
//検索レコードの総数を取得
count_size = [select count() from Account where name like:searchName and type like:searchType limit 100];
}else {
//flag = true;
resultFlag = false;
//error = 'no found data';
//system.debug('3343434==='+sq.size());
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索条件に該当するデータがありません!'));
//system.debug('flag'+flag);
}
}else{
//system.debug('yyyyy='+strCondName);
//不満足条件な検索 メッセージ提示
if(String.isBlank(strCondName) || String.isBlank(strCondType)){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '【取引先名】と【種別】を入力してください !'));
return;
}
else if(strCondName.containsAny('%') || strCondType.containsAny('%')){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '「%」以外のキーワードを入力してください !'));
return;
}
else if(strCondName.length()==1 || strCondType.length()==1){
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索語【取引先名】か【種別】には 2 文字以上を指定する必要があります!'));
return;
}
else{
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.WARNING, '検索条件に該当するデータがありません!'));
return;
}
}
}
//検索したレコードをクリア
public void clear(){
//検索結果一覧非表示
resultFlag = false;
//system.debug('111='+prds);
if(accResult!=null){
// system.debug('222='+prds);
//レコードをクリア
accResult.clear();
//入力欄もクリア
strCondName = '';
strCondType = '';
}else{
strCondName = '';
strCondType = '';
// error = '';
}
}
//キャンセル操作、何もない、画面をリフレッシュ
public PageReference cancel() {
return null;
}
//保存ボタン押下する、呼び出しメソッド
public PageReference save() {
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.INFO, '保存しました。'));
//system.debug('act name:' + act.name + ' = ' + act.accountNumber);
upsert act;
return null;
}
//Account削除メソッド
public void doDelete() {
SavePoint sp = Database.setSavepoint(); //トランザクションの制御
try {
String sfid = ApexPages.currentPage().getParameters().get('id'); //Visualforce1.vfpからのidを取得
List<Account> deleteList= [select Id from Account where Id=:sfid]; //データベースと合わせて
if (deleteList.size() == 0) {
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.ERROR, 'すでに削除されました。'));
} else {
delete deleteList;
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.INFO, '削除しました。'));
accounts= [select Id,Name,Type,Industry,phone from Account order by createddate desc limit 50 ]; //レコード更新
}
} catch(exception ex) {
system.debug('Error:'+ex.getMessage());
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.ERROR, ex.getMessage()));
Database.rollback(sp); //savepoint の生成時点と同じ状況にデータベースを復元
}
}
}
説明:
①getCount_size()
count_size = [select count() from Account where name like:strCondName and type like:strCondType limit 100];
count() :レコードの総数を計算
https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql.htm
②exactSearch()
精確検索 流れ:
画面からの 取引先名と種別をデータベース中に検索処理、満足条件と不満足条件 判断、できる場合、検索結果に値を格納して、
③search()
曖昧検索 流れ:
画面からの 取引先名と種別をデータベース中に検索処理、満足条件と不満足条件 判断、できる場合、検索結果に値を格納して、
select id,name,password from users where username='123' or '1'='1' and password='123' or '1'='1
select id,name,password
from users where username='123' or 1=1 #' and password='123' or 1=1 #'
select id,name,password
from users where username='123' or 1=1
md5暗号化およびその他のテクノロジーに対応したほうがいいと思います。
今回の「%」に対してちょっと説明させて頂きたいと思います。
もしかして、APEXの中に「%」の判断がない場合、検索結果はどうなっているのか?
これを見てみましょう。
もし、strCondName とstrCondType はすべて「%」で入力する、
select name,id,Type,Industry,phone from Account where like:% and like:% limit 100
実際の検索結果:
nameの値あるとtypeの値あるのレコードはすべて検索できるように。これは予想以外だと思います。
select name,id,Type,Industry,phone from Account where name=’%’ and type=’%’ limit 100
よく注意してくださいませね。
以上となります。
何か問題がございましたら、コメントを頂れば幸せです。
Latest posts by zchao (see all)
- Auraでアクションボタン作成して画面のチェックボックス項目一括処理 - 2021年4月12日
- デフォルト項目値を含むレコード作成実例説明(defaultFieldValues) - 2021年1月9日
- Salesforce のノーコード・ローコード開発 - 2020年12月31日
转载请注明:zchao博客之家 » Apex+VisualforceでAccountオブジェクトのCRUDとページングクエリー精確検索、曖昧検索(006)