Android エミュレータのSDカードにファイルを配置する
まずエミュレータにSDカードを作成します。
エクリプスのメニューより「ウィンドウ」→「AVDマネージャー」を選択します。
開いたダイアログよりSDカードを作成するエミュレータを選択し「編集」ボタンをクリックします。
SDカードに512MのSDカードを作成しました。
「AVDの編集」をクリックしダイアログを終了します。
SDカードが作成できたら「開始」ボタンでエミュレータを起動します。
エミュレータが起動したらエクリプスのメニューより「ウィンドウ」→「パースペクティブを開く」→「その他」→「DDMS」を選択します。
「ファイル・エクスプローラ」タブにsdcardが見えていると思います。
私のエミュレータではmntフォルダの下にsdcardが有りました。
最初はトップ階層のsdcardだと思って「なんでフォルダじゃないんだろう」なんて悩んでしまいました。
情報列の「mnt/sdcard」の意味がわからなかった・・・
右上の「pull a file」ボタンと[push a file」ボタンでSDカードにファイルを配置したり取り出したりできます。
私の環境では日本語名のファイルは「push a file」ボタンで配置できませんでした。
DDMSでファイルを配置できない場合は、コマンドプロンプトから以下のコマンドを入力します。
※ファイルを配置するには
>adb push C:\Sample.txt /sdcard/
adb push <PCにあるファイル> <デバイスのフォルダ>
※ファイルを取り出すには
adb pull <デバイスファイル名> <PCのファイル名>
Android TabActivityとTabHostを使用してTab画面を表示する
2012/11/19 追記
TabHostを使用する方法はAndroid 3.0 以降は非推奨となりました。
TabHostを使用せずにタブ画面を表示する方法はコチラ
Android ActionBarとFragmentを使用してTab画面を表示する(Android 4.0以上)
Android ActionBarとFragmentを使用してTab画面を表示する(Android 2.x)
むかし2年程前にタブメニューについて調べたんです。コレ→「Android タブ画面を表示する」 今回タブを使おうと思って昔の記事を読んでみたんですが・・・全然わかんないわぁ(;´д`) 自分で読んでも何を書いてるのかわかんないのに、二人の人が役にたったとリアクションしてくれてます。ゴメンナサイ 結局、私の役にはたたなかったので、ほかの人のブログを参考にしました。 自分の調べた事をメモるブログなのに意味ないしっ(>_<) 気を取り直して、再度調べた事をまとめておきます。 タブメニューを作成するにはTabHostウィジェットを使用します。 ActivityにTabHostを配置し、ActivityのonCreate()でTabHostにタブを追加します。 各タブをクリックしたときに表示するコンテンツですが、以下の3通りがあるようです。
TabHostを使用する方法はAndroid 3.0 以降は非推奨となりました。
TabHostを使用せずにタブ画面を表示する方法はコチラ
Android ActionBarとFragmentを使用してTab画面を表示する(Android 4.0以上)
Android ActionBarとFragmentを使用してTab画面を表示する(Android 2.x)
むかし2年程前にタブメニューについて調べたんです。コレ→「Android タブ画面を表示する」 今回タブを使おうと思って昔の記事を読んでみたんですが・・・全然わかんないわぁ(;´д`) 自分で読んでも何を書いてるのかわかんないのに、二人の人が役にたったとリアクションしてくれてます。ゴメンナサイ 結局、私の役にはたたなかったので、ほかの人のブログを参考にしました。 自分の調べた事をメモるブログなのに意味ないしっ(>_<) 気を取り直して、再度調べた事をまとめておきます。 タブメニューを作成するにはTabHostウィジェットを使用します。 ActivityにTabHostを配置し、ActivityのonCreate()でTabHostにタブを追加します。 各タブをクリックしたときに表示するコンテンツですが、以下の3通りがあるようです。
- TabHostを配置したアクティビティに定義したViewを表示する。
- 他のアクティビティを表示する
- layoutファイルに定義したViewを表示する
TabHostを配置したアクティビティに定義したViewを表示する
ActivityにTabHostを配置します。 アウトラインを見ると以下のようになっていると思います。TabHost(id/tabhost) |--LinearLayout |--TabWidget(id/tabs) |--FrameLayout(id/tabcontent) |--LinearLayout(id/tabs1) |--LinearLayout(id/tabs2) |--LinearLayout(id/tabs3)注意点は以下の3点です。
- TabHostはidがtabhostであること。
- TabWidgetはidがtabsであること。
- FrameLayoutはidがtabcontentであること。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TabHost android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TabWidget android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" > </TabWidget> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:id="@+id/tab1" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Tabページ1" /> </LinearLayout> <LinearLayout android:id="@+id/tab2" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Tabページ2" /> </LinearLayout> <LinearLayout android:id="@+id/tab3" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Tabページ3" /> </LinearLayout> </FrameLayout> </LinearLayout> </TabHost> </RelativeLayout>タブ部分に表示するテキストをres/values/strings.xmlに定義します。
<resources> : : <string name="tab1">ページ1</string> <string name="tab2">ページ2</string> <string name="tab3">ページ3</string> </resources>ActivityはTabActivityを継承して作成し、onCreate()でTabHostに各タブを追加していきます。 TabSpec#setIndicator()でタブ部分の文字を指定します。 TabSpec#setContent()でタブをクリックした時に表示するViewのidを指定します。 ここではactivity_main.xmlにある3つのLinearLayoutのidです。 MainActivity.java
public class MainActivity extends TabActivity { private static final String TAB[] = {"tab1", "tab2","tab3" }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //TabHostオブジェクト取得 TabHost tabhost = getTabHost(); //Tab1設定 TabSpec tab1 = tabhost.newTabSpec(TAB[0]); tab1.setIndicator(this.getResources().getString(R.string.tab1)); tab1.setContent(R.id.tab1); tabhost.addTab(tab1); //Tab2設定 TabSpec tab2 = tabhost.newTabSpec(TAB[1]); tab2.setIndicator(this.getResources().getString(R.string.tab2)); tab2.setContent(R.id.tab2); tabhost.addTab(tab2); //Tab3設定 TabSpec tab3 = tabhost.newTabSpec(TAB[2]); tab3.setIndicator(this.getResources().getString(R.string.tab3)); tab3.setContent(R.id.tab3); tabhost.addTab(tab3); //初期表示するタブ tabhost.setCurrentTab(0); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
他のアクティビティを表示する
次はタブをクリックした時に表示するコンテンツにActivityを指定する方法です。 まずTabHostを配置したメインとなるアクティビティを1つ作成します。 そしてタブをクリックした時に表示するアクティビティをタブの数だけ作成します。 つまりタブが3つある画面であれば4つのアクティビティを作成することになります。 各タブのコンテンツとなるアクティビティ「Tab1Activity.java」、「Tab2Activity.java」、「Tab3Activity.java」を作成します。 各アクティビティには、それぞれの違いがわかるように適当にウィジェットを配置しておきます。 次にメインとなるActivityを作成します。 こちらは「TabHostを配置したアクティビティに定義したViewを表示する」で作成したMainActivity.javaとほぼ同じです。 違いは、TabSpec#setContent()でアクティビティを指定します。 MainActivity.javapublic class MainActivity extends TabActivity { private static final String TAB[] = {"tab1", "tab2","tab3" }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //TabHostオブジェクト取得 TabHost tabhost = getTabHost(); //Tab1設定 TabSpec tab1 = tabhost.newTabSpec(TAB[0]); tab1.setIndicator(this.getResources().getString(R.string.tab1)); tab1.setContent(new Intent().setClass(this, Tab1Activity.class)); tabhost.addTab(tab1); //Tab2設定 TabSpec tab2 = tabhost.newTabSpec(TAB[1]); tab2.setIndicator(this.getResources().getString(R.string.tab2)); tab2.setContent(new Intent().setClass(this, Tab2Activity.class)); tabhost.addTab(tab2); //Tab3設定 TabSpec tab3 = tabhost.newTabSpec(TAB[2]); tab3.setIndicator(this.getResources().getString(R.string.tab3)); tab3.setContent(new Intent().setClass(this, Tab3Activity.class)); tabhost.addTab(tab3); //初期表示するタブ tabhost.setCurrentTab(0); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }この方法はアクティビティがいっぱいになるのがイヤだな・・・
layoutファイルに定義したViewを表示する
最後にTabをクリックした時に表示するコンテンツに、res/layoutに作成したファイルを表示する方法です。 これが一番よいのではと思っています。 res/layoutを右クリックし「新規」→「その他」→「Android XML レイアウト・ファイル」を選択し 「tab1.xml」、「tab2.xml」、「tab3.xml」を作成します。 ルート要素はLinearLayoutにし、それぞれの違いがわかるように適当にウィジェットを配置しておきます。 次にメインとなるActivityを作成します。 こちらは「TabHostを配置したアクティビティに定義したViewを表示する」で作成したMainActivity.javaとほぼ同じです。 違いは、TabSpec#setContent()でTabContentFactoryインターフェースを実装したクラスを指定します。 TabContentFactoryのcreateTabContent()メソッドで先ほど作成したレイアウトファイルを返すようにします。 MainActivity.javapublic class MainActivity extends TabActivity { private static final String TAB[] = {"tab1", "tab2","tab3" }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //タブに表示するViewをlayoutより取得する LayoutInflater layout = LayoutInflater.from(MainActivity.this); final View viewTab1 = layout.inflate(R.layout.tab1, null); final View viewTab2 = layout.inflate(R.layout.tab2, null); final View viewTab3 = layout.inflate(R.layout.tab3, null); //TabHostオブジェクト取得 TabHost tabhost = getTabHost(); //Tab1設定 TabSpec tab1 = tabhost.newTabSpec(TAB[0]); tab1.setIndicator(this.getResources().getString(R.string.tab1)); tab1.setContent(new TabHost.TabContentFactory (){ public View createTabContent(String tag) {return viewTab1;} }); tabhost.addTab(tab1); //Tab2設定 TabSpec tab2 = tabhost.newTabSpec(TAB[1]); tab2.setIndicator(this.getResources().getString(R.string.tab2)); tab2.setContent(new TabHost.TabContentFactory (){ public View createTabContent(String tag) {return viewTab2;} }); tabhost.addTab(tab2); //Tab3設定 TabSpec tab3 = tabhost.newTabSpec(TAB[2]); tab3.setIndicator(this.getResources().getString(R.string.tab3)); tab3.setContent(new TabHost.TabContentFactory (){ public View createTabContent(String tag) {return viewTab3;} }); tabhost.addTab(tab3); //初期表示するタブ tabhost.setCurrentTab(0); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }今回はちゃんとまとめられたと思うっ( *`ω´)
Android AlertDialogに画像を表示する
以前のAndroid AlertDialogを表示する の「独自のレイアウトを表示する」方法を利用してAlertDialogに画像を表示します。
画像の用意
まずAlertDialogに配置する画像を用意します。 画像はファイルエクスプローラーから\res\drawableフォルダに直接配置します。 drawableフォルダがなければ作成してください。 Androidは .png ( 推奨 )、.jpg ( 容認 )、.gif ( 非推奨 ) の 3つのフォーマットのビットマップをサポートします。 Eclipseが画像を自動で認識して、プロジェクトエクスプローラのres/drawableにそれぞれの画像が表示されます。 画像が読み込まれない場合、メニュー「プロジェクト」→「クリーン」を行ってください。リソースファイルの用意
AlertDialogのメッセージの文字色を白色にしたいので、色リソースを定義します。 Eclipseのプロジェクトエクスプローラのres/valuesを右クリックし「新規」→「その他」→「Android XML 値ファイル」を選択します。 ファイル名を「color」としルート要素に「resources」を選択します。 白色を定義します。 res/values/color.xml<?xml version="1.0" encoding="utf-8"?> <resources> <color name="white">#FFFFFF</color> </resources>
レイアウトファイルの用意
Eclipseのプロジェクトエクスプローラのres/layoutを右クリックし「新規」→「その他」→「Android XML レイアウト・ファイル」を選択します。 ファイル名を「alert」としルート要素に「LinearLayout」を選択しました。 レイアウトファイルには 画像を表示するためのImageViewとメッセージを表示するためのTextViewを配置します。 TextViewのTextColorは先ほど作成した色リソースの白を指定します。 色リソースがEclipseに認識されない場合はプロジェクトのクリーンを行ってください。 res/layout/alert.xml<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:id="@+id/imageAlertIcon" android:layout_width="60dp" android:layout_height="60dp" /> <TextView android:id="@+id/lblMessage" android:layout_width="258dp" android:layout_height="match_parent" android:text="TextView" android:textColor="@color/white" /> </LinearLayout>
AlertDialogを表示するクラスの用意
AlertDialogを表示するクラスAlertHelperクラスを作成します。(ここら辺はおこのみで) レイアウトファイルの用意で作成したalertレイアウトを取得し ImageViewに画像を、TextViewにメッセージを表示します。public class AlertHelper { /** * 警告メッセージを表示します。 * @param context * @param message * @param listenerOK */ public static void showWarning(Context context,String message,DialogInterface.OnClickListener listenerOK){ LayoutInflater inflater = LayoutInflater.from(context); final View view = inflater.inflate(R.layout.alert,null); ImageView imgAlertIcon = (ImageView)view.findViewById(R.id.imageAlertIcon); imgAlertIcon.setImageResource(R.drawable.warning); TextView lblMessage = (TextView)view.findViewById(R.id.lblMessage); lblMessage.setText(message); AlertDialog.Builder alert = new AlertDialog.Builder(context); alert.setPositiveButton("OK",listenerOK); alert.setView(view); alert.show(); } /** * エラーメッセージを表示します。 * @param context * @param message * @param listenerOK */ public static void showError(Context context,String message,DialogInterface.OnClickListener listenerOK){ LayoutInflater inflater = LayoutInflater.from(context); final View view = inflater.inflate(R.layout.alert,null); ImageView imgAlertIcon = (ImageView)view.findViewById(R.id.imageAlertIcon); imgAlertIcon.setImageResource(R.drawable.error); TextView lblMessage = (TextView)view.findViewById(R.id.lblMessage); lblMessage.setText(message); AlertDialog.Builder alert = new AlertDialog.Builder(context); alert.setPositiveButton("OK",listenerOK); alert.setView(view); alert.show(); } /** * 情報メッセージを表示します。 * @param context * @param message * @param listenerOK */ public static void showInformation(Context context,String message,DialogInterface.OnClickListener listenerOK){ LayoutInflater inflater = LayoutInflater.from(context); final View view = inflater.inflate(R.layout.alert,null); ImageView imgAlertIcon = (ImageView)view.findViewById(R.id.imageAlertIcon); imgAlertIcon.setImageResource(R.drawable.information); TextView lblMessage = (TextView)view.findViewById(R.id.lblMessage); lblMessage.setText(message); AlertDialog.Builder alert = new AlertDialog.Builder(context); alert.setPositiveButton("OK",listenerOK); alert.setView(view); alert.show(); } /** * 質問メッセージを表示します。 * @param context * @param message * @param listenerOK */ public static void showQuestion(Context context,String message,DialogInterface.OnClickListener listenerYes,DialogInterface.OnClickListener listenerNo){ LayoutInflater inflater = LayoutInflater.from(context); final View view = inflater.inflate(R.layout.alert,null); ImageView imgAlertIcon = (ImageView)view.findViewById(R.id.imageAlertIcon); imgAlertIcon.setImageResource(R.drawable.question); TextView lblMessage = (TextView)view.findViewById(R.id.lblMessage); lblMessage.setText(message); AlertDialog.Builder alert = new AlertDialog.Builder(context); alert.setPositiveButton("YES",listenerYes); alert.setNegativeButton("NO", listenerNo); alert.setView(view); alert.show(); } }質問メッセージを表示してみます。
public class MainActivity extends Activity { public void button1Click(View view) { OnClickListener listenerYes = new OnClickListener(){ public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "Yes", Toast.LENGTH_LONG).show(); } }; AlertHelper.showQuestion(this, "質問メッセージです。", listenerYes , null); } }
Android SDカードに配置したデータベースにアクセスする
SDカードに配置したデータベースにアクセスするには
マニフェストファイルにSD カードのコンテンツの変更/削除の権限を与える設定を行います。
SQLiteOpenHelperを継承したクラスのデータベース名にSDカードのデータベースパスを指定します。
マニフェストファイルにSD カードのコンテンツの変更/削除の権限を与える設定を行います。
SQLiteOpenHelperを継承したクラスのデータベース名にSDカードのデータベースパスを指定します。
public class DatabaseHelperTest extends SQLiteOpenHelper { /* データベース名 */ //private final static String DB_NAME = "HelloAndroid.db"; private final static String DB_NAME = Environment.getExternalStorageDirectory() + "/HelloAndroid.db"; /* データベースのバージョン */ private final static int DB_VER = 1; /* * コンストラクタ */ public DatabaseHelperTest(Context context) { super(context, DB_NAME, null, DB_VER); } @Override public void onCreate(SQLiteDatabase db) { // TODO 自動生成されたメソッド・スタブ } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO 自動生成されたメソッド・スタブ } }あとは従来通りにsqlを発行すればOKです。
Android SDカードに配置したデータベースをデータベースフォルダにコピーする
SDカードに配置したSQLiteデータベースをデータベースフォルダにコピーします。
public class MainActivity extends Activity { public void button1Click(View view){ try { final String DB_NAME = "HelloAndroid.db"; //既存データベースを削除 this.deleteDatabase(DB_NAME); //コピー元パス(SDカード) String pathFrom = Environment.getExternalStorageDirectory().getPath() + "/" + DB_NAME; //コピー先パス(データベースフォルダ) String pathTo = this.getDatabasePath(DB_NAME).getPath(); //コピー FileInputStream fis = new FileInputStream(pathFrom); FileChannel channelFrom = fis.getChannel(); FileOutputStream fos = new FileOutputStream(pathTo); FileChannel channeTo = fos.getChannel(); try { channelFrom.transferTo(0, channelFrom.size(), channeTo); } finally { fis.close(); channelFrom.close(); fos.close(); channeTo.close(); } } catch (Exception e) { e.printStackTrace(); } } }DatabaseHelperのonCreateでやれば良いと思う。
Android SDカードのファイルを読み書きする
実機で実行している場合、「マウント」をOFFします。
(SDカードに書き込みできず、マウントOFFに気づくのに小一時間゜・(ノД`)・゜・)
マニフェストファイルにSD カードのコンテンツの変更/削除の権限を与える設定を行います。
※SDカードから読み込むだけなら必要ありません。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>SDカードは端末によりパスが異なるのでgetExternalStorageDirectory()メソッドでパスを取得します。
String sdPath = Environment.getExternalStorageDirectory().getPath();あとは普通のファイル入出力と同じです。 SDカードに書き込み
public void button1Click(View view) { try { //SDカードフォルダのパス String sdPath = Environment.getExternalStorageDirectory().getPath(); //作成するファイル名 String fileName = "/Hello.txt"; //書き込み BufferedWriter bw = null; try { FileWriter fw = new FileWriter(sdPath + fileName); bw = new BufferedWriter(fw); bw.write("ハロー"); } finally { bw.close(); } } catch (Exception e) { e.printStackTrace(); } }SDカードに書き込み
public void button2Click(View view) { try { //SDカードフォルダのパス String sdPath = Environment.getExternalStorageDirectory().getPath(); //読み込むァイル名 String fileName = "/Hello.txt"; //読み込み BufferedReader br = null; try { FileReader fr = new FileReader(sdPath + fileName); br = new BufferedReader(fr); StringBuilder sb = new StringBuilder(); String str; while((str = br.readLine()) != null){ sb.append(str +"\r\n"); } Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show(); } finally { br.close(); } }catch (Exception e){ e.printStackTrace(); } }
.NET OracleデータベースのデータをSQLiteデータベースに移送する
前回、VisualStudioでSQLiteを使用できるようにしました。
.NET VisualStudioでSQLiteを使用する
今回は既存のOracleデータベースの選択したテーブルから、SQLiteにテーブルを作成しデータを移送するコードです。
データ移送がメンドイので作りました。自分用のメモです。
画面を表示するとリストボックスにOracleデータベースのテーブル一覧が表示されます。
SQLiteDB選択ボタンでデータを移送するSQLiteデータベースを選択してください。
データ移送ボタンで処理を実行します。
.NET VisualStudioでSQLiteを使用する
今回は既存のOracleデータベースの選択したテーブルから、SQLiteにテーブルを作成しデータを移送するコードです。
データ移送がメンドイので作りました。自分用のメモです。
画面を表示するとリストボックスにOracleデータベースのテーブル一覧が表示されます。
SQLiteDB選択ボタンでデータを移送するSQLiteデータベースを選択してください。
データ移送ボタンで処理を実行します。
Imports System.Data.Common Public Class FrmOracleToSqlite Private Const CONNECTION_STRING_PC As String = "user id=xxxxx;password=xxxxx;data source=xxxxx" Private Const PROVIDER_NAME_PC As String = "System.Data.OracleClient" Private _ConnectionStringAndroid As String = "data source={0}" Private Const PROVIDER_NAME_ANDROID As String = "System.Data.SQLite" Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load SetTableNameList() End Sub Private Sub cmdSelectDb_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdSelectDb.Click Using dialog As New OpenFileDialog If dialog.ShowDialog() = Windows.Forms.DialogResult.OK Then Me._ConnectionStringAndroid = String.Format(Me._ConnectionStringAndroid, dialog.FileName) Me.lblDbNm.Text = Me._ConnectionStringAndroid End If End Using End Sub Private Sub cmdExec_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExec.Click If Me.lstTableName.CheckedItems.Count = 0 Then MessageBox.Show("テーブルを選択して下さい。") Return End If System.Windows.Forms.Cursor.Current = Cursors.WaitCursor For Each sTableName As String In Me.lstTableName.CheckedItems CreateTableForAndroid(sTableName) Next MessageBox.Show("終了~!") End Sub '-----Private----- Private Sub SetTableNameList() Dim factory As DbProviderFactory = DbProviderFactories.GetFactory(PROVIDER_NAME_PC) Dim tbl As New DataTable Using cnn As DbConnection = factory.CreateConnection() cnn.ConnectionString = CONNECTION_STRING_PC cnn.Open() Try Using cmd As DbCommand = cnn.CreateCommand cmd.CommandText = "select table_name from user_tables order by table_name" Using adp As DbDataAdapter = factory.CreateDataAdapter adp.SelectCommand = cmd adp.Fill(tbl) End Using End Using Finally cnn.Close() End Try End Using 'cnn For idx As Integer = 0 To tbl.Rows.Count - 1 Me.lstTableName.Items.Add(tbl.Rows(idx).Item(0).ToString, False) Next End Sub Private Sub CreateTableForAndroid(ByVal sTableName As String) Dim factoryPC As DbProviderFactory = DbProviderFactories.GetFactory(PROVIDER_NAME_PC) Dim factoryAD As DbProviderFactory = DbProviderFactories.GetFactory(PROVIDER_NAME_ANDROID) 'PC側テーブル情報を取得 Dim tblSchema As New DataTable Dim tblPKey As New DataTable Using cnn As DbConnection = factoryPC.CreateConnection() cnn.ConnectionString = CONNECTION_STRING_PC cnn.Open() Try Using adp As DbDataAdapter = factoryPC.CreateDataAdapter '--列情報 Using cmd As DbCommand = cnn.CreateCommand adp.SelectCommand = cmd Dim sbSql As New System.Text.StringBuilder With sbSql .AppendLine("select") .AppendLine(" C.Column_Name") .AppendLine(" ,C.Data_type") .AppendLine(" ,C.Data_precision") .AppendLine(" ,C.Data_scale") .AppendLine(" ,C.Nullable") .AppendLine("FROM USER_TAB_COLUMNS C") .AppendLine(" INNER JOIN USER_TABLES T ON") .AppendLine(" C.Table_Name = T.Table_Name") .AppendLine("WHERE") .AppendLine(" T.Table_Name='" & sTableName & "'") End With cmd.CommandText = sbSql.ToString adp.Fill(tblSchema) End Using '--主キー情報 Using cmd As DbCommand = cnn.CreateCommand adp.SelectCommand = cmd Dim sbSql As New System.Text.StringBuilder With sbSql .AppendLine("SELECT") .AppendLine(" B.COLUMN_NAME AS COL_NAME") .AppendLine("FROM USER_CONSTRAINTS A") .AppendLine(" LEFT JOIN USER_CONS_COLUMNS B ON") .AppendLine(" B.TABLE_NAME = A.TABLE_NAME") .AppendLine(" AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME") .AppendLine("WHERE") .AppendLine(" B.TABLE_NAME = '" & sTableName & "'") .AppendLine(" AND A.CONSTRAINT_TYPE = 'P'") End With cmd.CommandText = sbSql.ToString adp.Fill(tblPKey) End Using End Using Finally cnn.Close() End Try End Using 'cnn 'Android側にテーブル作成 '--Drop文作成 Dim sSqlDrop As String = "DROP TABLE " & sTableName '--主キーリスト作成 Dim lstPKey As New List(Of String) For Each r As DataRow In tblPKey.Rows lstPKey.Add(r.Item("COL_NAME").ToString) Next '--Create文作成 Dim sqlCreate As New System.Text.StringBuilder With sqlCreate .AppendLine("CREATE TABLE " & sTableName & "(") For idx As Integer = 0 To tblSchema.Rows.Count - 1 If idx <> 0 Then .Append(",") End If .Append(tblSchema.Rows(idx).Item("Column_Name").ToString) Select Case tblSchema.Rows(idx).Item("Data_type").ToString Case "VARCHAR2", "DATE" .Append(" TEXT") Case "NUMBER" If CInt(tblSchema.Rows(idx).Item("data_scale")) = 0 Then .Append(" NUMBER") Else .Append(" REAL") End If End Select If tblSchema.Rows(idx).Item("Nullable").ToString = "N" Then .Append(" NOT NULL") End If .AppendLine("") Next sqlCreate.AppendLine(",PRIMARY KEY (" & String.Join(",", lstPKey.ToArray) & ")") sqlCreate.AppendLine(")") End With '--テーブル作成 Using cnn As DbConnection = factoryAD.CreateConnection() cnn.ConnectionString = Me._ConnectionStringAndroid cnn.Open() Try Using adp As DbDataAdapter = factoryAD.CreateDataAdapter Using cmd As DbCommand = cnn.CreateCommand cmd.CommandText = sSqlDrop Try cmd.ExecuteNonQuery() Catch ex As Exception '何もしない End Try cmd.CommandText = sqlCreate.ToString cmd.ExecuteNonQuery() End Using End Using Finally cnn.Close() End Try End Using 'cnn 'データ移送 Const DATA_CNT As Integer = 100 Dim iSt As Integer = 0 Dim iEd As Integer = iSt + DATA_CNT - 1 '--PC側データのSELECT文の作成 Dim sqlSelect As New System.Text.StringBuilder With sqlSelect .AppendLine("SELECT TMPTABLE2.* FROM") .AppendLine(String.Format("(SELECT ROWNUM AS ROW_NUM, {0}.* FROM {0} ) TMPTABLE2", sTableName)) .AppendLine("WHERE ROW_NUM >= :ROW_NUM_Sta") .AppendLine("AND ROW_NUM <= :ROW_NUM_End") End With Dim cmdSelect As DbCommand = factoryPC.CreateCommand cmdSelect.CommandText = sqlSelect.ToString Dim pSt As DbParameter = factoryPC.CreateParameter pSt.ParameterName = "ROW_NUM_Sta" cmdSelect.Parameters.Add(pSt) Dim pEd As DbParameter = factoryPC.CreateParameter pEd.ParameterName = "ROW_NUM_End" cmdSelect.Parameters.Add(pEd) '--Android側のInsert文の作成 Dim lstColNm As New List(Of String) Dim lstPrmmNm As New List(Of String) For Each row As DataRow In tblSchema.Rows lstColNm.Add(row.Item("Column_Name").ToString) lstPrmmNm.Add("@" & row.Item("Column_Name").ToString) Next Dim sqlInsert As New System.Text.StringBuilder With sqlInsert .AppendLine("INSERT INTO " & sTableName & "(") .AppendLine(String.Join(","c, lstColNm.ToArray)) .AppendLine(")VALUES(") .AppendLine(String.Join(","c, lstPrmmNm.ToArray)) .AppendLine(")") End With Dim cmdInsert As DbCommand = factoryAD.CreateCommand cmdInsert.CommandText = sqlInsert.ToString For Each colnm As String In lstColNm Dim prm As DbParameter = factoryAD.CreateParameter prm.ParameterName = colnm prm.SourceColumn = colnm prm.SourceVersion = DataRowVersion.Current cmdInsert.Parameters.Add(prm) Next '--データをSelectしInsertをDATA_CNT件づつ繰り返す Using cnnPC As DbConnection = factoryPC.CreateConnection() cnnPC.ConnectionString = CONNECTION_STRING_PC cnnPC.Open() Try Using cnnAd As DbConnection = factoryAD.CreateConnection() cnnAd.ConnectionString = Me._ConnectionStringAndroid cnnAd.Open() Try cmdSelect.Connection = cnnPC cmdInsert.Connection = cnnAd Do '----Select実行 Dim tblSelect As New DataTable Using adp As DbDataAdapter = factoryPC.CreateDataAdapter adp.SelectCommand = cmdSelect cmdSelect.Parameters(pSt.ParameterName).Value = iSt cmdSelect.Parameters(pEd.ParameterName).Value = iEd adp.Fill(tblSelect) End Using If tblSelect.Rows.Count = 0 Then Exit Do End If '----取得したデータの行状態を追加にする For Each row As DataRow In tblSelect.Rows row.SetAdded() Next '----Insert実行 Using adp As DbDataAdapter = factoryAD.CreateDataAdapter adp.InsertCommand = cmdInsert adp.Update(tblSelect) End Using '----インクリメント iSt = iEd + 1 iEd = iSt + DATA_CNT - 1 Loop Finally cnnAd.Close() End Try End Using 'cnnAd Finally cnnPC.Close() End Try End Using 'cnnPC End Sub End Class
登録:
投稿 (Atom)
-
DataTableから重複を除くには と DataTableの集約計算を行う(Compute) を利用して、DataTableをグループ化し集計を行います。 以下のようなデータが入ったDataTableから、Field1とField2で重複を取り除き集計をおこないます。...
-
前回「 PLSQL SELECTの結果を取得する ~取得結果が1行の場合~ 」に続き 今回はSELECTの結果が複数行の場合です。 SELECTの結果が複数行の場合はカーソルを使用します。 カーソルとは SELECTの結果セットに対して、1行ずつデータを取り出し、順次...
-
datatableの集約計算を行うにはDataTable.Compute メソッドを使用します。 Dim As Object '最大値を求める value = datatable.Compute("Max(集計列名)", Nothing) ...