Ajan työssäni SAP BWsta exceliin raakadataa ja sitä sitten sortataan ja analysoidaan useissa eri excel taulukoissa. Edeltänäni tässä työssä on luonut muutamia toimivia makroja, mutta vielä on paljon manuaalista copy-paste toimintaa josta haluasin päästä eroon.
Kysymys: nauhoittamalla makron tai kirjoittamalla koodia VBA:lla on helppo valita jokin tietty kiinteä solualue. Mutta kuinka valitaan taulukon loppupäästä aina esim. viimeiset 5 solua sarakkeesta A? Joka päivä/viikko/kuukausi (riippuen taulusta) taulun rivimäärä lisääntyy ja siksi kiinteä alueviittaus ei toimi. Tämä on varmasti tosi yksinkertaista mutta kun ohjelmointikokemusta ei ole ja vasta viime viikolla tein ensimmäisiä alkeellisia pätkiä VBA:lla, niin en vielä keksinyt tähän ratkaisua.
Kiitos vastauksista jo etukäteen!
Tässä yksi vaihtoehto.
Sub ValitseLoppu() Dim I As Long 'Etsitään ensimmäinen tyhjä solu sarakkeesta A For I = 1 To 65000 If Cells(I, "A").Value = "" Then Exit For Next I 'Valitaan tyhjän solun yläpuolelta 5 riviä Range("A" & I - 1 & ":A" & I - 6).Select End Sub
Thanks Meitzi! Täytyy kokeilla huomenna että miten toimii. Selkeä ohje, kiitos!
Moro Taavetti!
testaa oheista simppeliä viritelmää...
'ThisWorkbook Private Sub Workbook_Activate() 'kutsutaan aliohjelmaa, joka lisää 'työkirjaan työkalurivin ja lisää siihen 'yhden komentopainikkeen... AddCmdBar End Sub Private Sub Workbook_Deactivate() 'kutsutaan aliohjelmaa joka 'poistaa luodun työkalurivin ja 'siinä olevan komentopainikkeen RemoveCmdBar End Sub Private Sub Workbook_SheetActivate(ByVal Sh As Object) 'Jos VBA-lomake on näkyvissä niin... If UserForm1.Visible Then 'kutsuataan seuraavia aliohjelmia: InitTaulut InitSarakkeet AsetaVRiviSarake 'asetetaan lomakkeen comboboxin 'listindex arvoksi aktiivisen taulun index 'arvo vähennettynä yhdellä... UserForm1.ComboBox1.ListIndex = ActiveSheet.Index - 1 'kutsutaan lomakkeelta aliohjelmaa 'joka asettaa valintojen arvot vastaamaan 'aktiivisen laskentataulkon vallitsevia asetuksia. UserForm1.InitTaulukosta End If End Sub
'Module1 'Alustetaan globaalit muuttujat Global Taulut() As String Global vrivi As Long Global vsarake As Long Global Sarakkeet() As String Sub InitTaulut() 'alustetaan paikalliset muuttujat Dim ws As Worksheet Dim cnt As Integer: cnt = -1 ReDim Taulut(ThisWorkbook.Sheets.Count - 1) 'aseteaan työkirjan laskentataulukoiden nimet 'merkkijonotyyppiseen taulukkomuuttujaan... For Each ws In ThisWorkbook.Worksheets cnt = cnt + 1 With ws Taulut(cnt) = .Name End With Next End Sub Sub InitSarakkeet() 'alustetaan paikalliset muuttujat... Dim i As Integer: Dim tmp() As String ReDim Sarakkeet(Sheets(1).Columns.Count - 1) 'aseteaan taulukkomuuttujan alkioiden 'arvoiksi sarakkeiden kirjainmääritteet... For i = 0 To UBound(Sarakkeet) tmp = Split(Replace(Sheets(1).Columns( _ i + 1).Address, "$", ""), ":") Sarakkeet(i) = tmp(0) Erase tmp Next End Sub Sub UserFormShow() 'Jos VBA-lomake ei ole näkyvissä 'ja työkalupalkin komentopainiketta '(Näytä Lomake)kilkataan niin ko. 'lomake tuodaan esiin... If Not UserForm1.Visible Then UserForm1.Show 0 End If End Sub Sub AsetaVRiviSarake() 'asetetaan muuttujan (vrivi) arvoksi 'aktiivisen laskentataulukon viimeisen 'käytössä olevan rivin indeksi... vrivi = ActiveSheet.Cells.SpecialCells( _ xlCellTypeLastCell).Row 'asetetaan muuttujan (vsarake) arvoksi 'aktiivisen laskentataulukon viimeisen 'käytössä olevan sarakkeen indeksi... vsarake = ActiveSheet.Cells.SpecialCells( _ xlCellTypeLastCell).Column End Sub Sub AddCmdBar() 'yritetään ensin poistaa mahdollisen virhe- 'tilanteen yhteydessä projektiin mahdollisesti 'jäänyt työkalurivi ennen uuden luomista... RemoveCmdBar On Error Resume Next 'alustetaan objektimuuttujat.... Dim CmdBar As CommandBar Dim CmdBtn As CommandBarButton 'luodaan objektit jne... Set CmdBar = Application.CommandBars.Add(Name:= _ "VBALOMAKE", Position:=msoBarTop, Temporary:=True) CmdBar.Visible = True Set CmdBtn = CmdBar.Controls.Add( _ Type:=msoControlButton, ID:=2949, Before:=1) With CmdBtn .Caption = "&Näytä lomake" .Style = msoButtonCaption .OnAction = "UserFormShow" End With If Err <> 0 Then Err.Clear: On Error GoTo 0 End If End Sub Sub RemoveCmdBar() 'poistetaan luotu painike ja työkalurivi On Error Resume Next Application.CommandBars("VBALOMAKE").Controls(1).Delete Application.CommandBars("VBALOMAKE").Delete If Err <> 0 Then Err.Clear: On Error GoTo 0 End If End Sub
'UserForm1 Private sallitut() As String Private Sub UserForm_Activate() 'Lomakkeen ohjauobjektit: '3 ComboBoxia (ComboBox1...ComboBox3) '1 Tekstiruutu (TextBox1) '2 Radionappia (OptionButton1 & OptionButton2) 1 Komentopainike (CommandButton1) 'kutsutaan aliohjelmia... InitTaulut InitSarakkeet AsetaVRiviSarake 'alustetaan objektien ominaisuusarvot ComboBox1.Style = fmStyleDropDownList ComboBox2.Style = fmStyleDropDownList ComboBox3.Style = fmStyleDropDownList ComboBox1.List = Taulut ComboBox1.ListIndex = ActiveSheet.Index - 1 ComboBox2.List = Sarakkeet ComboBox3.List = Sarakkeet ComboBox2.ListIndex = 0 OptionButton1.Value = True 'täytetään taulukkomuuttuja sallitut = Split("1,2,3,4,5,6,7,8,9,0", ",") End Sub Private Sub ComboBox1_Change() 'kun comboboxin valintaa muutetaan 'aktivoidaan comboboxin tekstiarvoa 'vastaava laskentataulukko... If ComboBox1.Text <> "" Then Sheets(ComboBox1.Text).Activate End If End Sub Private Sub ComboBox2_Change() 'tutkitaan comboboxin valinnan muuttumisen 'yhteydessä ylittyytkö asetetut rajaarvot... If ComboBox2.ListIndex > vsarake - 1 Then MsgBox "Valittu sarake ylittää käytetyn alueen" ComboBox2.ListIndex = vsarake - 1 End If ComboBox3.ListIndex _ = ComboBox2.ListIndex End Sub Private Sub ComboBox3_Change() 'tutkitaan comboboxin valinnan muuttumisen 'yhteydessä ylittyytkö asetetut raja-arvot... If ComboBox3.ListIndex > vsarake - 1 Then MsgBox "Valittu sarake ylittää käytetyn alueen" ComboBox3.ListIndex = vsarake - 1 End If End Sub Private Sub CommandButton1_Click() 'alustetaan paikalliset muuttujat... Dim i As Long, alue As Range 'ehdollistetaan koodin suoritustapa 'valintapainikkeen Value -arvon mukaan... If OptionButton1.Value = True Then Set alue = Range(ComboBox2.Text & "1:" _ & ComboBox3.Text & TextBox1.Text) alue.Select: Set alue = Nothing Else Dim erivi As Long: erivi = _ vrivi - CLng(TextBox1.Text) + 1 Set alue = Range(ComboBox2.Text & CStr( _ erivi) & ":" & ComboBox3.Text & CStr(vrivi)) alue.Select: Set alue = Nothing End If End Sub Private Sub TextBox1_Change() If Len(TextBox1.Text) > 0 Then 'tutkitaan onko ensimmäisen merkin arvo 0 If Val(Left(TextBox1.Text, 1)) = 0 Then TextBox1.Text = "1": Exit Sub End If 'alustetaan paikalliset muuttujat... Dim i As Integer Dim tmp As String Dim validi As Boolean 'tutkitaan syötettyjen merkkien kelvollisuus jne... For i = 1 To Len(TextBox1.Text) validi = False For j = 0 To UBound(sallitut) If Mid(TextBox1.Text, i, 1) = sallitut(j) Then validi = True: Exit For End If Next j If validi Then tmp = tmp + Mid(TextBox1.Text, i, 1) End If Next i TextBox1.Text = tmp End If If Val(TextBox1.Text) > vrivi Then MsgBox "Rivimäärä ylittää käytetyn alueen!" TextBox1.Text = CStr(vrivi) End If TextBox1.SelStart = Len(TextBox1.Text) End Sub Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) 'jos tekstiruutuun jäi tyhjäke poistuttaessa 'niin asetetaan ko. objektin merkkijonoarvoksi: "1" If TextBox1.Text = "" Then TextBox1.Text = "1" End If End Sub Public Sub InitTaulukosta() 'asetetaan lomakkeen objektien ominaisuusarvot 'vastaamaan aktiivisen laskentataulukon asetuksia '(tätä kutsutaan, kun laskentataulukko aktivoidaan) If ComboBox2.ListIndex > vsarake - 1 Then ComboBox2.ListIndex = vsarake - 1 End If If ComboBox3.ListIndex > vsarake - 1 Then ComboBox3.ListIndex = vsarake - 1 End If If Val(TextBox1.Text) > vrivi Then TextBox1.Text = CStr(vrivi) End If End Sub
Mikäli jotain on epäselvää niin imppaa täältä valmis Excel(2003)/VBA-projekti+.
Lähetänpä tässä aiheeseen liittyvä nauhoitetun makron. Yritin muokata tuota niin, että poistin "valitaan ensimmäinen kopioitava tieto..." alta molemmat Range -valinnat ja lisäsin tilalle Meitzin lähettämän pätkän ilman sub/end subia. "A" tilalle laitoin "AA" kuten makroesimerkin Range valinnassakin. Ei toiminut. Kiitos myös Neau33:lle, vastauksessasi on kenties ratkaisu ongelmaan. En vain tällä parin päivän makron nauhoitus/VBA kokemuksella kykene hahmottamaan sitä, simmpeliydestään huolimatta...Taavetti
Mod. lisäsi kooditagit!
Sub weekly_update() ' ' weekly_update Makro ' tämä on nauhoitettu makro ja tässä ongelmana kiinteä alueviittaus. Kopioitava alue tulisi olla kussakin kopiointitapahtumassa sarakkeen viisi viimeisintä arvoa. Jos viimeinen arvo on kuitenkin nolla, niin kopioitavat arvot ovat sarakkeen viisi viimeistä suurempi kuin nolla (>0) arvoa. Windows("Orders & operating rate 2012.xls").Activate 'tyhjennetään vanhat arvot, turhaan tosin, mutta näkyypähän kohdealue. Range("F7:J14,F17:J20,F24:J27,F30:J31,F35:J38").Select Range("F35").Activate Selection.ClearContents 'valitaan ensimmäinen kopioitava tieto ja liitetään transponoimalla Windows("Ca order inflow.xls").Activate Range("AA265:AA269").Select Range("AA269").Activate Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F8").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan toinen kopioitava tieto ja liitetään transponoimalla Windows("Ca order inflow.xls").Activate Range("AB265:AB269").Select Range("AB269").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F10").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan kolmass kopioitava tieto ja liitetään transponoimalla Windows("Ca order inflow.xls").Activate Range("AC265:AC269").Select Range("AC269").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F12").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan neljäs kopioitava tieto ja liitetään transponoimalla Windows("Ca order inflow.xls").Activate Range("AG265:AG269").Select Range("AG269").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F14").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan viides kopioitava tieto ja liitetään transponoimalla Windows("Ca order inflow.xls").Activate Range("D265:D269").Select Range("D269").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F18").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan kuudes kopioitava tieto ja liitetään transponoimalla Windows("Ca order inflow.xls").Activate Range("E265:E269").Select Range("E269").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F20").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan seitsemäs kopioitava tieto ja liitetään transponoimalla Windows("orderstocks new organisation.XLS").Activate Sheets("Home Office data").Select ActiveWindow.SmallScroll Down:=-3 Range("I210:I214").Select Range("I214").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F25").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan kahdeksas kopioitava tieto ja liitetään transponoimalla Windows("orderstocks new organisation.XLS").Activate Range("U210:U214").Select Range("U214").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F27").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan yhdeksäs kopioitava tieto ja liitetään transponoimalla Windows("orderstocks new organisation.XLS").Activate Sheets("Speciality Papers").Select Range("K210:K214").Select Range("K214").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F31").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan kymmenes kopioitava tieto ja liitetään transponoimalla Windows("orderstocks new organisation.XLS").Activate Range("I210:I214").Select Range("I214").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F36").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan yhdestoista kopioitava tieto ja liitetään transponoimalla Windows("order inflow.xls").Activate Sheets("Order Inflow data").Select Range("AN108:AN112").Select Range("AN112").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F7").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan kahdestoista kopioitava tieto ja liitetään transponoimalla Windows("order inflow.xls").Activate Range("AO108:AO112").Select Range("AO112").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F9").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan kolmastoista kopioitava tieto ja liitetään transponoimalla Windows("order inflow.xls").Activate Range("AQ108:AQ112").Select Range("AQ112").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F11").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan neljästoista kopioitava tieto ja liitetään transponoimalla Windows("order inflow.xls").Activate Range("AP108:AP112").Select Range("AP112").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F13").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan viidestoista kopioitava tieto ja liitetään transponoimalla Windows("order inflow.xls").Activate Range("P108:P112").Select Range("P112").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F17").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan kuudestoista kopioitava tieto ja liitetään transponoimalla Windows("order inflow.xls").Activate Range("BJ108:BJ112").Select Range("BJ112").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F19").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan seitsemästoista kopioitava tieto ja liitetään transponoimalla Windows("order inflow.xls").Activate Sheets("Office papers").Select Range("B109:B113").Select Range("B113").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F24").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan kahdeksastoista kopioitava tieto ja liitetään transponoimalla Windows("order inflow.xls").Activate Range("C109:C113").Select Range("C113").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F26").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan yhdeksästoista kopioitava tieto ja liitetään transponoimalla Windows("order inflow.xls").Activate Range("F109:F113").Select Range("F113").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Range("F30").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True 'valitaan kahdeskymmenes kopioitava tieto ja liitetään transponoimalla Windows("order inflow.xls").Activate Sheets("Speciality").Select Range("J109:J113").Select Range("J113").Activate Application.CutCopyMode = False Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Windows("order inflow.xls").Activate ActiveWindow.SmallScroll Down:=-75 Windows("Orders & operating rate 2012.xls").Activate Range("F37").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True End Sub
Mod. lisäsi kooditagit!
Eli tällaisella allaolevalla pätkällä testasin juuri äsken. Tarkoitus oli testimielessä valita "Ca order inflow.xls" -taulusta AA sarakkeen viisi alinta solua, eli makronauhoituksen ensimmäisen kopioitavan tiedon valinta ("AA265:AA269"). Ei toiminut tuo valinta. Keltaiseksi meni tämä:
Range("AA" & I - 1 & ":AA" & I - 6).Select
Mitähän tein väärin?
yst.terveisin, Taavetti
Sub testi1() ' ' testi1 Makro ' ' Windows("Ca order inflow.xls").Activate Dim I As Long 'Etsitään ensimmäinen tyhjä solu sarakkeesta A For I = 1 To 65000 If Cells(I, "AA").Value = "" Then Exit For Next I 'Valitaan tyhjän solun yläpuolelta 5 riviä Range("AA" & I - 1 & ":AA" & I - 6).Select Selection.Copy Windows("Orders & operating rate 2012.xls").Activate Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True End Sub
Mod. huom: Ainakin kooditagit teit väärin. Ole hyvä ja lue keskustelun ohjeet!
Moi taas Taavetti!
On tosi nastaa, että tutkit/kokeilet/yhdistät koodia, mutta tutki ja testaa oheista viritelmää ensin ihan sellaisenaan...
'Työkirjan 'Ca order inflow.xls' 'laskentataulukkoon 'Taul1' sijoitetun 'komentopainikkeen Click_tapahtuman koodi... 'koodin suorittaminen kopioi 'Taul1' viiden viimeismmän käytetyn 'sarakkeen viiden viimeisimmä arvon sisältävän solun arvon ensin 'väliaikaisen taulun 'temp' alueelle ("A1:E5"), josta arvot kopioidaan 'edelleen sarkkeittain työkirjan 'Orders & operating rate 2012.xls 'laskentataulukon 'Taul1' (target_Sheet) viiden viimeisimmän käytössä 'olevan ei tyhjän sarakkeen viiteen ensimmäiseen tyhjään soluun. Private Sub CommandButton1_Click() Application.ScreenUpdating = False Application.DisplayAlerts = False Dim IsOpen As Boolean Dim wk As Workbook Dim ws As Worksheet Set ws = ThisWorkbook.Sheets("Taul1") For Each wk In Workbooks With wk If .Name = "Orders & operating rate 2012.xls" Then IsOpen = True: Exit For End If End With Next If Not IsOpen Then 'Huom! molempien .xls tiedostojen 'tulee sijaita samassa kansiossa Dim xlPath As String xlPath = Replace(ActiveWorkbook.FullName, ActiveWorkbook.Name, "") Workbooks.Open xlPath & "Orders & operating rate 2012.xls" End If ThisWorkbook.Activate ws.Activate Dim lastrow As Long, lastcol As Long, i As Long lastrow = ws.Cells.SpecialCells(xlCellTypeLastCell).Row lastcol = ws.Cells.SpecialCells(xlCellTypeLastCell).Column For i = lastrow To 1 Step -1 If Application.CountA(ws.Rows(i).EntireRow) <> 0 Then Exit For End If If i = 1 Then Exit For lastrow = i Next For i = lastcol To 1 Step -1 If Application.CountA(ws.Columns(i).EntireColumn) <> 0 Then Exit For End If If i = 1 Then Exit For lastcol = i Next Dim startrow As Long, startcol As Long If lastcol > 5 Then startcol = lastcol - 5 Else startcol = 1 End If On Error Resume Next ThisWorkbook.Sheets("temp").Delete If Err <> 0 Then Err.Clear On Error GoTo 0 End If ThisWorkbook.Worksheets.Add ActiveSheet.Name = "temp" ws.Activate Dim rowcoun As Integer Dim colcount As Integer For i = startcol To lastcol rowcount = 6 colcount = colcount + 1 For j = lastrow To 1 Step -1 If Cells(j, i).Value > 0 Then rowcount = rowcount - 1 Sheets("temp").Cells(rowcount, _ colcount).Value = Cells(j, i).Value End If If rowcount = 1 Then Exit For Next j Next i Dim target_Sheet As Worksheet Dim target_lastrow As Long Dim target_lastcol As Long Set target_Sheet = _ Workbooks("Orders & operating rate 2012.xls").Sheets("Taul1") target_lastrow = target_Sheet.Cells.SpecialCells(xlCellTypeLastCell).Row target_lastcol = target_Sheet.Cells.SpecialCells(xlCellTypeLastCell).Column For i = target_lastrow To 1 Step -1 If Application.CountA(target_Sheet.Rows(i).EntireRow) <> 0 Then Exit For End If If i = 1 Then Exit For target_lastrow = i Next For i = target_lastcol To 1 Step -1 If Application.CountA(target_Sheet.Columns(i).EntireColumn) <> 0 Then Exit For End If If i = 1 Then Exit For target_lastcol = i Next Dim target_startcol As Long Dim target_endcol As Long If target_lastcol < 5 Then target_startcol = 1 Else target_startcol = target_lastcol - 4 End If target_endcol = target_startcol + 4 Dim target_row As Long, _ source_address As String, _ address_parts() As String, _ target_address As String colcount = 0 For i = target_startcol To target_endcol colcount = colcount + 1 target_row = target_lastrow + 1 For j = target_lastrow To 1 Step -1 If target_Sheet.Cells(j, i).Value <> "" Then Exit For End If target_row = j Next j address_parts = Split(Replace(Sheets("temp").Columns( _ colcount).address, "$", ""), ":") source_address = address_parts(0) & "1:" & address_parts(0) & "5" target_address = Replace(target_Sheet.Cells( _ target_row, i).address, "$", "") target_address = target_address & ":" & target_address ThisWorkbook.Sheets("temp").Range(source_address).Copy _ target_Sheet.Range(target_address) Erase address_parts Next i Set target_Sheet = Nothing ThisWorkbook.Sheets("temp").Delete Workbooks("Orders & operating rate 2012.xls").Save Workbooks("Orders & operating rate 2012.xls").Close Application.DisplayAlerts = True Application.ScreenUpdating = True End Sub
Halutessasi voit impata täältä valmiin Excel(2003)/VBA-projektin
Kiitos Nea! Kokeilen taas töissä huomenna.
Kommenttiin: "Mod. huom: Ainakin kooditagit teit väärin. Ole hyvä ja lue keskustelun ohjeet!"
Vastaan, että luin kyllä ohjeet ja katsoin mallia Nean ja Meitzin kooditageista. Valitettavasti en tiedä/osaa erotella tuolta koodista oleellista. Ja nyt huomasin, että Ohjelmointiputkan etusivulla lukee "Ohjelmointiputka on suomalaisten ohjelmoijien kokoontumispaikka". Eli olen IT-osaamiseeni nähden eksynyt väärään seuraan ja siitä johtuu tahaton huono käytökseni.
t. Taavetti
Et ole ollenkaan väärässä seurassa.
Taavetti kirjoitti:
Eli tällaisella allaolevalla pätkällä testasin juuri äsken. Tarkoitus oli testimielessä valita "Ca order inflow.xls" -taulusta AA sarakkeen viisi alinta solua, eli makronauhoituksen ensimmäisen kopioitavan tiedon valinta ("AA265:AA269"). Ei toiminut tuo valinta. Keltaiseksi meni tämä:
Range("AA" & I - 1 & ":AA" & I - 6).Select
Mitähän tein väärin?
Tuo koodi toimii omassa Excel 2010:ssä täysin oikein. (eli saraakkeesta AA kopioi tietoa ja liittää sen toiseen asiakirjaan sinne missä kohdistin siellä sattuu olemaan)
Toki tuo ei oli optimaalisin tapa tehdä asia, mutta se on varmasti sellainen minkä itse ymmärrät. Ja se on tässävaiheessa tärkeämpi kuin se, onko ratkaisu hieno.
Tässä siis juuri se koodi mitä testasin ja toimi.
Sub testi1() Windows("Työkirja1.xlsm").Activate Dim I As Long 'Etsitään ensimmäinen tyhjä solu sarakkeesta AA For I = 1 To 65000 If Cells(I, "AA").Value = "" Then Exit For Next I 'Etsitään ylöspäinensimmäinen ei nolla For I = I - 1 To 0 Step -1 If Cells(I, "AA").Value <> 0 Then Exit For Next I 'Valitaan 5 riviä Range("AA" & I - 5 & ":AA" & I).Select Selection.Copy Windows("Työkirja2.xlsm").Activate Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True End Sub
(tuli mieleen että onko mahdollista, että joku office versio ei anna valita negatiivista selectiä, jote muutin sen)
Aihe on jo aika vanha, joten et voi enää vastata siihen.