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 SubThanks 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 SubMikä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 SubMod. 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 SubMod. 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 SubHalutessasi 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.