CSV-formaattiin tallennus toimii suoraan Excelin taulukosta aivan OK, pilkut säilyvät tekstitiedostossa desimaalierottimina ja puolipisteet toimivat luetteloerottimina. Mutta sitten se VBA. Tehtäessä tuo tallennus VBA-makrolla (vaikkapa suoraan nauhoittamalla tallennus csv-muodossa) tulee desimaalierottimeksi piste ja luetteloerottimeksi pilkku.
SaveAs metodilla on kolmekin eri csv:n FileFormat-muotoa, mutta mikään niistä ei vaikuta tallentuvan csv-tiedoston desimaali-/luetteloerottimiin.
Saman ongelman kanssa paininut useasti.
SaveAs metodilla tuo ei onnistukaan, ohessa MS:n selvitys aiheesta.
Itse olen käyttänyt usein seuraavaa tapaa:
Dim filepathtemp As String, filepathcsv As String Dim buffer As String filepathtemp = "C:\temp\temp.csv" filepathcsv = "C:\CSV_Files\tiedosto1.csv" ActiveWorkbook.SaveAs Filename:=filepathtemp, FileFormat:=xlCSV, CreateBackup:=False Open filepathtemp For Binary Access Read As 1 buffer = Space(LOF(1)) Get #1, , buffer Close 1 'vaihdetaan pilkut puolipisteeksi buffer = Replace(buffer, ",", ";") 'vaihdetaan pisteet(desimaalierotin) pilkuiksi buffer = Replace(buffer, ".", ",") Open filepathcsv For Binary Access Write As 1 Put #1, , buffer Close 1
edit: http://www.cpearson.com/excel/ImpText.aspx <-- tuolla myös yksi ratkaisu
Moikka alfac!
tässä olis yhdenlainen viritelmä samasta aiheesta...
UserForm1:
'Formille ListBoxi, 2 TextBoxia, 2 labelia
'checkboxi ja 2 komentonappia.
'säädöt:
'ListBoxi: multiSelect arvoksi=True
'TextBoxit: MaxLength arvoiksi 1
'märitellään julkinen boolean-muuttuja
Public kaikki As Boolean
Private Sub CheckBox1_Click()
'tutkitaan muuttujan totuusarvo
Select Case kaikki
'jos arvo on EPÄTOSI
Case False
'asetetaan silmukassa kaikkien taulujen
'valittu-arvoksi TOSI...
For i = 0 To ListBox1.ListCount - 1
ListBox1.Selected(i) = True
Next i
'...asetetaan muuttujan totuusarvoksi TOSI
'ja poistutaan aliohjelmasta.
kaikki = True: Exit Sub
'jos arvo on TOSI
Case True
For i = 0 To ListBox1.ListCount - 1
'asetetaan silmukassa kaikkien muiden taulujen
'paitsi aktiiviseksi määritellyn taulun...
'valittu-arvoksi EPÄTOSI
If ListBox1.List(i) <> taulu Then
ListBox1.Selected(i) = False
End If
Next i
'...asetetaan muuttujan totuusarvoksi EPÄTOSI
kaikki = False
End Select
End Sub
Private Sub CommandButton1_Click()
'Tutkitaan TekstiBoxien sisällöt
Select Case TextBox1.Text
'jos vaihtoehtoista erotinmerkkiä
'ei ole määritelty TextBox'ssa niin
'eroitimen arvoksi jätettään oletus
Case Is = ""
kerotin = ";"
'muutoin arvoksi asetetaan TextBox1'n teksti
Case Else
kerotin = TextBox1.Text
End Select
'jne...
Select Case TextBox2.Text
Case ""
terotin = ""
'jos tietue-erotin on asetettu...
Case Else
'...muutujan arvoksi asetetaan TextBox2'n teksti
terotin = TextBox2.Text
End Select
'käydään ListBoxin aktivoidut valinnat
'silmukassa lävitse...
For i = 0 To ListBox1.ListCount - 1
'...jos laskurin osoittaman indeksin
'mukainen valinta on aktivoitu niin...
If ListBox1.Selected(i) Then
'...sijoitetaan kyseisen valinnan
'arvo merkkijonomuuttujaan...
taulu = ListBox1.List(i)
'siirrytään aliohjelmaan:
maaritaTaulu
'siirrytään aliohjelmaan:
csvTallennus
End If
Next i
'siirrytään taphtuma-aliohjelmaan
'(CommandButton2_Click)
CommandButton2 = True
End Sub
Private Sub CommandButton2_Click() '(Peruuta)
'ladataan formi pois muistista
Unload Me
End Sub
Private Sub UserForm_Activate()
'asetetaan julkiseksi määritetyn
'boolean-muuttujan totuusarvoksi EPÄTOSI
kaikki = False
'Nollataan ListBoxin sisältö
ListBox1.Clear
Dim t As Worksheet
'Poimitaan silmukassa aktiivisen työkirjan nimet
For Each t In Worksheets
With t
'ja sisällytetään nimet ListBoxin listlle
ListBox1.AddItem .Name
If .Name = taulu Then ListBox1.Selected(ListBox1.ListCount - 1) = True
End With
Next
End SubThisWorkbook:
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean) taulu = ActiveSheet.Name If Not UserForm1.Visible Then UserForm1.Show End Sub
Module1:
'määritellään julkiset muuttujat
Public taulu As String, tkirja As String
Public rivit As Long, sarakkeet As Long
Public terotin As String, kerotin As String
Sub auto_open()
'Avattaessa työkirja:
'aktivoidaan taulu-indeksin perusteella työkirjan 1. taulu
Sheets(1).Activate
'sijoitetaan aktivoidun taulun nimi merkkijonomuuttujaan
taulu = Sheets(1).Name
End Sub
Public Sub maaritaTaulu()
'määritellään paikallinen merkkijonomuuttuja
Dim sarake As String
'sijoitetaan sekä aktiivisen työkirjan että taulu nimi,
'julkisiksi määriteltyihin merkkijonomuuttujiin
tkirja = Application.ActiveWorkbook.Name
If taulu = "" Then taulu = Sheets(1).Name
Sheets(taulu).Activate
'estetään näytön turha päivittyminen
Application.ScreenUpdating = False
'etsitään taulun viiemisen, jonkin arvon omaavan
'sarakkeen ja viimeisen, jonkin arvon omaavan rivin
'perusteella alueen viimeisen solun osoite ja
'sijoitetaan saatu arvo paikalliseen merkkijono-
'muuttujaan, poistaen samalla saadusta arvosta
'dollari-merkit($).
sarake = Replace(Sheets(taulu).Cells.SpecialCells _
(xlCellTypeLastCell).Address, "$", "")
'aktivoidaan aktiivisesta taulusta alue, joka muodostuu
'taulun ensimmäisen solun (A1) ja edellä etsityn, alueen
'viimeisen solun muodostamasta alueesta, jolloin voidaan
'poimia alueen viimeisen rivin sekä sarakkeen sijainti
'lukuna rivi/sarakelaskureiden indeksien perusteella...
Sheets(taulu).Range("A1:" & sarake).Select
'...sijoitetaan saadut arvot,julkisiksi märiteltyihin
'long-tyyppisiin kokonaislukumuuttujiin
rivit = Selection.Rows.Count
sarakkeet = Selection.Columns.Count
'aktivoidaan ensimmäinen solu...
Cells(1, 1).Select
'...ja sallitaan näytön päivittyminen
Application.ScreenUpdating = True
End Sub
Public Sub csvTallennus()
'alustetaan range-tyyppiset objektit ja merkkijonomuuttuja
Dim tietue As Range
Dim kentta As Range
Dim stringi As String
'avataan työpöydälle tekstitiedosto ja nimetään
'formaatissa 'Työkirja_taulu.csv'
Open Environ("userprofile") & "\Työpöytä\" _
& tkirja & "_" & taulu & ".csv" For Output As #1
'käydään aktiivisessa taulussa läpi aliohjelmassa
'maaritaTaulu määritetyn alueen rivit rivi kerrallaan...
For Each tietue In Range("A1:A" & rivit)
With tietue
'käydään aktiivisessa taulussa, tämän aliohjelman
'laskuri-indeksin osoittaman rivi/sarakkeindeksin
'määrittelemät kentät (= solut) lävitse
For Each kentta In Range(.Cells(1), Cells(.Row, sarakkeet))
'lisätään paikalliseen merkkijonomuuttujaan kentän
'sisältö tekstinä + kenttäeroitin
rivi = rivi & kerotin & kentta.Text
Next kentta
'mikäli tietue-erotin on esetettu, lisätään
'erotin jokaisen rivin (=tietue) loppuun
If terotin <> "" Then rivi = rivi & teroitin
'tulostetaan avoimeen tiedostoon, silmukassa muodostettu rivi,
'jättäen kuitenkin rivin ensimmäinen merkki tulostamatta
Print #1, Mid(rivi, 2)
'alustetaan merkkijonomuuttuja uutta silmukan
'kierrosta varten antamalla sille arvoksi tyhjä.
rivi = Empty
End With
Next tietue
'suljetaan avoin tiedosto
Close #1
End SubKiitos infosta ja ideoista Hycke ja Neau33!
Ehdin itsekin eilen aamulla kaivella verkkoa ja löysin sieltä vielä yhden tavan tehdä tuo kirjoitus (http://www.ozgrid.com/forum/showthread.php?t=37476&highlight=csv). Tässä siitä ideasta sovellettu tapa kirjoittaa csv, joka tuntuu toimivan kuin junan vessa. Comments?
Dim ETunnus As String
Dim VTunnus As String
Dim Tiedosto As String
Dim VSarake As Integer
Dim VRivi As Long
Dim Rivi As Long
Dim Sarake As Integer
Dim Nro As Integer
Const Erotin = ";"
Range("A1").Select
EHanke = ActiveCell.Text
Selection.End(xlDown).Select
VTunnus = ActiveCell.Text
' nimetään tiedosto automaattisesti ensimmäinen tunnus_viimeinen tunnus
Tiedosto = "C:\Siirrot\" + "ETunnus + "_" + VTunnus + ".csv"
Nro = FreeFile
'haetaan viimeinen sarake ja viimeinen rivi
With ActiveSheet.Cells
VSarake = .Find("*", [A1], , , xlByColumns, xlPrevious).Column
VRivi = .Find("*", [A1], , , xlByRows, xlPrevious).Row
End With
' avataan tekstitiedosto kirjoitusta varten
Open Tiedosto For Output As #Nro
' kirjoitetaan rivit sarake kerrallaan erotettuna puolipisteellä
For Rivi = 1 To VRivi
For Sarake = 1 To VSarake
Print #Nro, ActiveSheet.Cells(Rivi, Sarake).Value & Erotin;
Next Sarake
Print #Nro,
Next Rivi
' suljetaan tiedosto
Close #NroAihe on jo aika vanha, joten et voi enää vastata siihen.