none
如何透過VB搜尋某一個EXCEL檔案內的字串 RRS feed

  • 問題

  • 想寫一個VB程式,進到D:\111.xls檔案裡面的所有sheet搜尋"aaa"字串,找到之後回傳右邊欄位的字串內容回VB的TextBox1。
    比如找到"aaa",欄位是B3,然後回傳B4, B5, B6的內容到TextBox1, TextBox2, TextBox3。

    目前小弟已經可以開啟EXCEL檔案,並將指定的欄位值回傳到TextBox...
    但是EXCEL內容常常變動,該特定字串欄位常常變動,所以想用搜尋的方式,靈活性比較大。

    小弟是VB新手,還請前輩們多多指教。
    若是問題描述不夠清楚,還請告知小弟。
    謝謝!

    2009年5月7日 上午 02:09

解答

  •         Dim FindCell As Object
            With xlsApp.activesheet
                FindCell = .Cells.Find(FFF)
                For i = 1 To 10
                    MsgBox(xlsApp.activesheet.Cells(FindCell.Row, i).value)
                    'Debug.Print(.Cells(FindCell.Row, i).value) '取值
                Next
     
                'If FindCell Is Nothing Then
                '    Me.TextBox1.Text = "Nothing"
                'Else
                '    Me.TextBox1.Text = FindCell.Value & FindCell.Address
                'End If
            End With
    改成以上試試囉...
    • 已標示為解答 老班 2009年5月7日 上午 08:10
    2009年5月7日 上午 07:18
  • Vb 2005 關閉excel
    http://social.msdn.microsoft.com/Forums/zh-TW/232/thread/4e002fb8-0486-426a-bc7c-a4eda693a2d3/


    參考此篇看看,FindCell才是找到字串Cell的位置,之前的方法似乎不是所找到的位置...
    • 已標示為解答 老班 2009年5月7日 上午 08:44
    • 已編輯 Joe Hung 2009年6月2日 下午 01:36
    2009年5月7日 上午 08:10
  •         Dim strTemp As String
            Dim intCount As Integer = 0
            sheetApp = xlsApp.sheets("Amplifier")
            For i As Integer = 3 To 100
                strTemp = sheetApp.cells(1, i).value
                If strTemp <> "" Then
                    'ReDim Preserve EVB(intCount)
                    'EVB(intCount) = strTemp
                    ComboBox_amp.Items.Add(strTemp)
                    intCount += 1
                End If
            Next

    請參考以上囉...
    • 已標示為解答 老班 2009年5月7日 上午 09:44
    2009年5月7日 上午 09:21
  •         Dim xlsApp As Object       
            Dim sheetApp As Object
            Dim intCount As Integer = 0
            Dim Findsw As Object
    
            xlsApp = CreateObject("Excel.Application")
            xlsApp.Workbooks.open("D:\Book1.xls")
            sheetApp = xlsApp.sheets("sw")
         
            With sheetApp
                Findsw = .Cells.Find(ComboBox_sw.Text)
                TextBox1.Text = .Cells(Findsw.Row, 2).value
                TextBox2.Text = .Cells(Findsw.Row, 3).value
            End With
            xlsApp.Workbooks.Close()
            xlsApp.quit()
            xlsApp = Nothing
            GC.Collect()

    是的,最好頭尾都再做一次...
    • 已標示為解答 老班 2009年5月11日 上午 09:03
    2009年5月11日 上午 09:00

所有回覆

  • http://www.programmer-club.com.tw/ShowSameTitleN/vb/33925.html

    您有在別的地方問過?哪裡還有問題?您是用VB6嗎?
    2009年5月7日 上午 02:31
  • Dim i As Integer
    Dim FFF As String = ComboBox_amp.Text
            With xlsApp.activesheet
                .Cells.Find(FFF)
                For i = 1 To 10
                    MsgBox(xlsApp.activesheet.Cells(xlsApp.ActiveCell.Row, i).value)
                Next
            End With

    小弟之前有在程式設計俱樂部發問過,當時作到一半,只作了簡單測試。
    可是後來就被其他事情中斷了...
    FAE雜事很多...
    直到昨天又重新把這拿來測試,發現不管我在ComboBox_amp選擇哪一項,
    MsgBox都只會回傳第9列 A1 ~ J9的值

    小弟是用VB2008 Express...

    2009年5月7日 上午 03:18
  •         Dim FindCell As Object
            With xlsApp.activesheet
                FindCell = .Cells.Find(FFF)
                For i = 1 To 10
                    MsgBox(xlsApp.activesheet.Cells(FindCell.Row, i).value)
                    'Debug.Print(.Cells(FindCell.Row, i).value) '取值
                Next
     
                'If FindCell Is Nothing Then
                '    Me.TextBox1.Text = "Nothing"
                'Else
                '    Me.TextBox1.Text = FindCell.Value & FindCell.Address
                'End If
            End With
    改成以上試試囉...
    • 已標示為解答 老班 2009年5月7日 上午 08:10
    2009年5月7日 上午 07:18
  • 謝謝您的解答,已經可以回傳10欄的值了。
    不過小弟對於設FindCell這個Object的理由是什麼?
    是因為原本的方式會造成取值誤讀嗎?

    另外再請教一個問題
    在程式執行完,要把Excel關閉
    小弟在網路上面找到的寫法幾乎都是:
    xlsApp.workbooks.close()
    xlsApp.quit()
    xlsApp = Nothing
    但是真正在檔案總管裡開啟這個Excel檔案,還是會出現檔案使用中,必須用唯讀或通知
    這表示VB程式根本沒關閉Excel
    是不是小弟語法寫錯了
    2009年5月7日 上午 07:34
  • Vb 2005 關閉excel
    http://social.msdn.microsoft.com/Forums/zh-TW/232/thread/4e002fb8-0486-426a-bc7c-a4eda693a2d3/


    參考此篇看看,FindCell才是找到字串Cell的位置,之前的方法似乎不是所找到的位置...
    • 已標示為解答 老班 2009年5月7日 上午 08:44
    • 已編輯 Joe Hung 2009年6月2日 下午 01:36
    2009年5月7日 上午 08:10
  • 再次感激您的解答!!!
    加了GC.Collect()果然就讓Excel完全關閉了

    不好意思再次請教...
    小弟想將Excel A欄裡有資料的儲存格中,把有資料的列集合成一維陣列
    {A1, A3, A4....}     ....A2是空白

    然而在一開始從Excel讀入A欄就發生錯誤

            sheetApp = xlsApp.sheets("Amplifier")

            For i As Integer = 3 To 100
                Dim EVB() As String = sheetApp.cells(i, 1)
                ComboBox_amp.Items.AddRange(EVB)
            Next

    無法將型別 'System.__ComObject' 的 COM 物件轉換為類別型別 'System.Object[]'。代表 COM 元件的型別執行個體,無法轉換為不代表 COM 元件的型別; 但只要基礎 COM 元件支援介面 IID 的 QueryInterface 呼叫,即可將其轉換為介面。

    小弟應該是把事情想得太簡單了吧...

    2009年5月7日 上午 08:44
  •         Dim strTemp As String
            Dim intCount As Integer = 0
            sheetApp = xlsApp.sheets("Amplifier")
            For i As Integer = 3 To 100
                strTemp = sheetApp.cells(1, i).value
                If strTemp <> "" Then
                    'ReDim Preserve EVB(intCount)
                    'EVB(intCount) = strTemp
                    ComboBox_amp.Items.Add(strTemp)
                    intCount += 1
                End If
            Next

    請參考以上囉...
    • 已標示為解答 老班 2009年5月7日 上午 09:44
    2009年5月7日 上午 09:21
  • 小弟對您真是感激不盡...
    這下把小弟要完成的程式解決的差不多了...
    只是...一些指令找書都沒有...
    比如GC.Collect(),還有這次的ReDim Preserve...
    總之還是很感謝您...
    小弟再繼續試試看完成這程式...
    2009年5月7日 上午 09:44
  • 不好意思再次請教...

    以Excel資料中,A2、A3、A4是合併儲存格,可是要如何設判斷式以及如何回傳B3~D3或B4~D4的值...
    以下圖為例:

         A   B   C   D
    -------------------
    1   a    5   o   m
    2   b    7   g   j
    3         8   r   i
    4         4   s   l
    5   c    3   q   e

    小弟笨拙...目前只能回傳B1~D1以及B5~D5的值...
    還請高手指導...



    2009年5月8日 上午 03:37
  •         Dim a As Object
            With xlsApp.activesheet
    
                For Each a In .UsedRange
                    If a.MergeCells Then
                        MsgBox(a(, 1).address)
                    End If
                Next
                For i = 1 To 5
                    Debug.Print(.Cells(i, 1).value) '取值
                Next
                For i = 2 To 4
                    Debug.Print(.Cells(3, i).value) '取值
                Next
                For i = 2 To 4
                    Debug.Print(.Cells(4, i).value) '取值
                Next
    
            End With

    不曉得是您要的嗎?參考看看囉...
    2009年5月8日 上午 05:06
  • 不好意思,今天事情太多,只顧著發問,還沒時間Try...
    小弟會趁假日試試看,若是可行,會上來回報...
    還是感謝您的大力幫助...
    2009年5月8日 上午 08:12
  • 感謝您的幫忙,小弟已經試出來讀出B1~D1以及B5~D5的值...
    可是現在有另一個小問題,一直找不到怎麼解決...

    以小弟的Excel file為例,一共有四個sheet,而第一個sheet搜尋取值程式如下:
    Private Sub ComboBox_amp_SelectedIndexChanged(ByVal ...) Handles ComboBox_amp.SelectedIndexChanged
            textbox_clear()
            With xlsApp.activesheet
                Dim Findamp As Object
                Findamp = .Cells.Find(ComboBox_amp.Text)
                '第一行
                TextBox1.Text = .Cells(Findamp.Row, 2).value
                TextBox2.Text = .Cells(Findamp.Row, 3).value
                TextBox3.Text = .Cells(Findamp.Row, 4).value
                TextBox4.Text = .Cells(Findamp.Row, 5).value
                TextBox5.Text = .Cells(Findamp.Row, 6).value
                ...
            End With
    End Sub

    而在搜尋取值第二個sheet卻發生問題
    Private Sub ComboBox_sw_SelectedIndexChanged(ByVal ...) Handles ComboBox_sw.SelectedIndexChanged
            textbox_clear()
            With xlsApp.activesheet
                Dim Findsw As Object
                Findsw = .Cells.Find(ComboBox_sw.Text)
                '第一行
                TextBox1.Text = .Cells(Findsw.Row, 2).value
                TextBox2.Text = .Cells(Findsw.Row, 3).value
                TextBox3.Text = .Cells(Findsw.Row, 4).value
                TextBox4.Text = .Cells(Findsw.Row, 5).value
                TextBox5.Text = .Cells(Findsw.Row, 6).value
                ...
            End With
    End Sub

    未設定物件變數或 With 區塊變數。

    小弟已經設了with語法,怎麼還會發生這樣的問題。
    還請您指正...

    2009年5月11日 上午 08:32
  • 小弟駑鈍,剛剛才想到程式一開始有作一個設定...
    Dim StrTemp As String
    Dim intCount As Integer = 0
    Dim EVB() As Object
    sheetApp = xlsApp.sheets("Amplifier")
         For i As Integer = 3 To 100
             StrTemp = sheetApp.cells(i, 2).value
             If StrTemp <> "" Then
                 ReDim Preserve EVB(intCount)
                 ComboBox_amp.Items.Add(StrTemp)
                 intCount += 1
             End If
          Next
    在每個RadioButtom checkchanged下都將sheetApp指定到各個sheet了
    因此在上一個問題中每個ComboBox選擇改變下,
    只要將With xlsApp.activesheet改成With sheetApp就行了...
    應該是這樣沒錯吧...
    2009年5月11日 上午 08:55
  •         Dim xlsApp As Object       
            Dim sheetApp As Object
            Dim intCount As Integer = 0
            Dim Findsw As Object
    
            xlsApp = CreateObject("Excel.Application")
            xlsApp.Workbooks.open("D:\Book1.xls")
            sheetApp = xlsApp.sheets("sw")
         
            With sheetApp
                Findsw = .Cells.Find(ComboBox_sw.Text)
                TextBox1.Text = .Cells(Findsw.Row, 2).value
                TextBox2.Text = .Cells(Findsw.Row, 3).value
            End With
            xlsApp.Workbooks.Close()
            xlsApp.quit()
            xlsApp = Nothing
            GC.Collect()

    是的,最好頭尾都再做一次...
    • 已標示為解答 老班 2009年5月11日 上午 09:03
    2009年5月11日 上午 09:00
  • 謝謝您的建議,也十分感謝您不厭其煩替小弟解決這些問題...
    這下就沒有其他問題了...
    2009年5月11日 上午 09:03
  • 不好意思,小弟又有其他問題...
            
           Dim FindCell As Object
            With xlsApp.activesheet
                FindCell = .Cells.Find(FFF)
                For i = 1 To 10
                    MsgBox(xlsApp.activesheet.Cells(FindCell.Row, i).value)
                    'Debug.Print(.Cells(FindCell.Row, i).value) '取值
                Next
            End With
    搜尋的語法,xlsApp.activesheet應該是指使用中的工作表吧
    照一開始的設定,xlsApp是活頁簿,sheetApp是工作表,但是小弟是靠指定工作表才能變成activesheet
    sheetApp = xlsApp.sheets("Amplifier")


    那如果小弟設了一個TextBox,在裡面輸入關鍵字(比如產品料號"AA123",但是"AA"可以忽略)
    該如何在整個活頁簿(三四個工作表)當中找到有這關鍵字的欄位?
    小弟在網路上找到Find語法,可是卻不知道怎麼套用
    還請高手指點

    2009年5月13日 上午 02:58
  •        Dim FindCell As Object

    sheetApp = xlsApp.sheets("Amplifier")

            With sheetApp
                FindCell = .Cells.Find(FFF)
                For i = 1 To 10
                    MsgBox(xlsApp.activesheet.Cells(FindCell.Row, i).value)
                    
                Next
            End With

    在下會把每個工作表都搜尋一次,也就是第一行改變字串,後面做一樣的事,您可以把找到的Find語法貼出來,參考看看囉...

    2009年5月13日 上午 03:13
  • Find語法:
    Cells.Find(What:="aaa", After:=ActiveCell).Activate

    其中What:欲尋找的目標,After:指定儲存格,尋找將從該儲存格後開始

    可是小弟套用語法:
    sheetApp.Cells.Find(What:="TextBox30.Text", After:=ActiveCell).Avtivate
    卻出現未宣告 ActiveCell

    小弟只是想說先試試看這指令是不是所要的,結果試不出所以然...

    那小弟先試試看您的方法,每個工作表都搜尋一次
    有進一步結果會立刻上來回報
    謝謝了
    2009年5月13日 上午 03:54
  • 小弟完成每個sheet依序搜尋,也可以找到欄位資料了...
    再次謝謝您的幫助~

    想請教其他的問題...
    小弟在Form1設置了MenuStrip,並且仿照一般功能表(檔案、編輯、檢視...)
    而在其中"開啟檔案"的程式如下:

    Private Sub 開啟檔案ToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 開啟檔案ToolStripMenuItem1.Click
            Dim openFileDialog1 As New OpenFileDialog()
            With openFileDialog1
                .Title = "開啟Excel檔案"
                .Filter = "Excel檔案(*.XLS)|*.xls|所有檔案(*.*)|*.*"
                .ShowDialog()
            End With
            If openFileDialog1.ShowDialog() = DialogResult.OK Then
            ???
            End If
        End Sub

    小弟在???處不知道該怎麼寫
    也就是我按下開啟檔案對話盒的確定鍵之後,要怎麼樣開啟excel檔案,或一般常見的檔案?(就如同在windows檔案總管一樣,開office文件或是pdf...)
    謝謝

    2009年5月14日 上午 01:25
  •         If openFileDialog1.FileName <> "" Then            
                'How to Wait for a Shelled Process to Finish
                'Get the name of the system folder.
                Dim sysFolder As String = _
                            Environment.GetFolderPath(Environment.SpecialFolder.System)
                'Create a new ProcessStartInfo structure.
                Dim pInfo As New ProcessStartInfo()
                'Set the file name member of pinfo to Eula.txt in the system folder.            
                pInfo.FileName = openFileDialog1.FileName
                'Start the process.
                Dim p As Process = Process.Start(pInfo)
                'Wait for the process window to complete loading.
                p.WaitForInputIdle()
                'Wait for the process to exit.
                p.WaitForExit()
                'Continue with the code.
                MessageBox.Show("Code continuing...")
            End If

    如何:等候 Shelled 應用程式完成使用 Visual Basic .NET
    http://support.microsoft.com/kb/305368/zh-tw

    建議不同主題,請另外發文詢問,以免討論串過長,其他人以為此討論已解決,而沒有回覆您...
    • 已編輯 Joe Hung 2009年6月2日 下午 01:37
    2009年5月14日 上午 02:01
  • 謝謝您的建議,小弟會注意這點
    小弟試著寫看看開啟檔案的程式
    多謝您的協助
    2009年5月14日 上午 02:18