Avatar billede sus82 Nybegynder
17. august 2011 - 19:12 Der er 21 kommentarer og
1 løsning

Hjælp, min makro kører i ring

Hej

Jeg har en makro der er event styret. Hvis celle BQ45 indeholder en værdi, skal en simpel kopiering af et område  foretages. Der er formler bag disse celler, men kun værdierne skal indsættes (Makro4).

Når dette er gjort vil det medføre at celle BQ45 bliver tom, og der derfor ikke foretages yderligere handlinger. I teorien.
Problemet er bare den, at processen med at "paste" værdier er for langsom
så makroen pisker bare rundt i ring. Er der nogen der kan hjælpe?
Den ser sådan her ud:

Private Sub Worksheet_Change(ByVal Target As Range)
   
       
      If Range("$BQ$45").Value <> "" Then
      Makro4
   
    End If

    End Sub

Makro4:

Sub Makro4()
'
' Makro4 Makro
'

'
    Range("BP47:BZ80").Select
    Selection.Copy
   
    Range("BP83").Select
    Selection.PasteSpecial Paste:=xlPasteAllUsingSourceTheme, Operation:=xlNone _
        , SkipBlanks:=False, Transpose:=False
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False
    Selection.Copy
   
    Range("CM26").Select
    ActiveSheet.Paste
End Sub
Avatar billede store-morten Ekspert
17. august 2011 - 20:20 #1
Prøv med:
Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Range("$BQ$45"), Target) Is Nothing Then
      If Not Target.Value <> "" Then
      Makro4
    End If
    End If
End Sub

Og:
Sub Makro4()
Application.ScreenUpdating = False

    Range("BP47:BZ80").Select
    Selection.Copy
   
    Range("BP83").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
   
    Range("CM26").Select
    ActiveSheet.Paste
   
    Application.CutCopyMode = False
Application.ScreenUpdating = True
    Range("$BQ$45").Select
End Sub
Avatar billede claes57 Ekspert
17. august 2011 - 20:18 #2
indlæg en pause på fx 5 sekunder - makro-hjælp har denne

If Application.Wait(Now + TimeValue("0:00:05")) Then
    MsgBox "Time expired"
End If


så du skifter bare
    MsgBox "Time expired"
ud med kaldet af Makro4
Avatar billede thekox Nybegynder
17. august 2011 - 20:22 #3
Private Sub Worksheet_Change(ByVal Target As Range)
   
       
    If Range("$BQ$45").Value <> "" Then
     
      Range("$BQ$45").Clear

      call Makro4
   
    End If

End Sub

-----------------------------------------------------------
Sub Makro4()
    Range("BP47:BZ80").copy   
    Range("BP83").pastespecial xlall
   
    Range("CM26").pastespecial xlall
    Application.CutCopyMode = False
End Sub
Avatar billede store-morten Ekspert
17. august 2011 - 20:33 #4
Private Sub Worksheet_Change(ByVal Target As Range 
      If Range("$BQ$45").Value <> "" Then
      Makro4

Ved ændring i ark og $BQ$45 er "" (Tom) så kør Makro4
Makro4 starter = ændring i ark og $BQ$45 er stadig "" (Tom): kør Makro4
Makro4 starter = ændring i ark og $BQ$45 er stadig "" (Tom): kør Makro4
Makro4 starter = ændring i ark og $BQ$45 er stadig "" (Tom): kør Makro4
Makro4 starter = ændring i ark og $BQ$45 er stadig "" (Tom): kør Makro4.....osv
Avatar billede sus82 Nybegynder
17. august 2011 - 22:43 #5
Tak for alle forslag.

Jeg har gennemgået alle.

thekox: Dit forslag sletter BQ45, hvor der er formler bag. Ikke så heldigt.

Store Morten: Der sker ikke noget, hvis jeg sætter din løsning ind.# 4 forstod jeg ikke.

claes57: En god ide - synes jeg - at lige gi' den nogle sekunder til at blive færdig med at sætte ind. Desværre har jeg ikke kunnet få det til at virke, da jeg er ny indenfor VBA og ikke ved hvordan den præcist skal skrives. Den skal konstatere at der er indhold i BQ45, sætte gang i makro4, og derefter vente 5 sekunder med at evaluere påny om der er indhold i BQ45. Hvad skal der helt præcist stå?

Tak, og sorry for ventetiden
Avatar billede store-morten Ekspert
17. august 2011 - 23:51 #6
Jeg mener det er som herunder.
Din kode
Private Sub Worksheet_Change(ByVal Target As Range)
   
       
      If Range("$BQ$45").Value <> "" Then
      Makro4
   
    End If

    End Sub


Gør at ved ændring i ark og $BQ$45 er "" (Tom) så kør Makro4
Makro4 starter = ændring i ark og $BQ$45 er stadig "" (Tom): kør Makro4
Makro4 starter = ændring i ark og $BQ$45 er stadig "" (Tom): kør Makro4
Makro4 starter = ændring i ark og $BQ$45 er stadig "" (Tom): kør Makro4
Makro4 starter = ændring i ark og $BQ$45 er stadig "" (Tom): kør Makro4.....osv

Derfor genstarter Marko4 igen og igen.

Erstat med:
Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Range("$BQ$45"), Target) Is Nothing Then
      If Not Target.Value <> "" Then
      Makro4
    End If
    End If
End Sub

Ved ændring i celle $BQ$45 og der er ændret til "" (Tom) så kør Makro4 eller gør intet.

Din kode:
Makro4:

Sub Makro4()
'
' Makro4 Makro
'

'
    Range("BP47:BZ80").Select
    Selection.Copy
   
    Range("BP83").Select
    Selection.PasteSpecial Paste:=xlPasteAllUsingSourceTheme, Operation:=xlNone _
        , SkipBlanks:=False, Transpose:=False
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False
    Selection.Copy
   
    Range("CM26").Select
    ActiveSheet.Paste
End Sub

Markerer celler BP47:BZ80 og kopiere dem.
Markerer celle BP83 og indsætter med et format.
Indsætter og overskiver med et andet format.
Tømmer udklipsholder.
Med markering, kopierer det der lige er slettet.
Markerer celle CM26 og indsætter.
Stopper med cellerne fra indsættelse markeret.

Erstat med:
Sub Makro4()
Application.ScreenUpdating = False

    Range("BP47:BZ80").Select
    Selection.Copy
   
    Range("BP83").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
   
    Range("CM26").Select
    ActiveSheet.Paste
   
    Application.CutCopyMode = False
Application.ScreenUpdating = True
    Range("$BQ$45").Select
End Sub

ScreenUpdating fra = så skærm ikke flimmer (Skjuler makro udførsel)
Markerer celler BP47:BZ80 og kopiere dem.
Indsætter med det andet format.
Markerer celle CM26 og indsætter.
ScreenUpdating til.
Markere celle $BQ$45

Altså en forenkling ;-) af Makro4
Avatar billede supertekst Ekspert
17. august 2011 - 23:35 #7
Måske:

Dim flag As Boolean              '<--
Private Sub Worksheet_Change(ByVal Target As Range)
    If Range("$BQ$45").Value <> "" And flag = False Then
        flag = True              '<--
        Makro4
        flag = False            '<--
    End If
End Sub
Sub Makro4()
    Range("BP47:BZ80").Select
    Selection.Copy
   
    Range("BP83").Select
    Selection.PasteSpecial Paste:=xlPasteAllUsingSourceTheme, Operation:=xlNone _
        , SkipBlanks:=False, Transpose:=False
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False
    Selection.Copy
   
    Range("CM26").Select
    ActiveSheet.Paste
End Sub
Avatar billede store-morten Ekspert
18. august 2011 - 00:09 #8
Hvis ikke Makro4 behøver at ligge for sig selv. Eks. i et modul.
Og format ikke er vigtigt?
Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Range("$BQ$45"), Target) Is Nothing Then
      If Not Target.Value <> "" Then
Application.ScreenUpdating = False
    Range("BP47:BZ80").Select
    Selection.Copy
    Range("BP83").Select
    ActiveSheet.Paste
    Range("CM26").Select
    ActiveSheet.Paste
    Application.CutCopyMode = False
    Range("$BQ$45").Select
Application.ScreenUpdating = True
    End If
    End If
End Sub

Med format:
Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Range("$BQ$45"), Target) Is Nothing Then
      If Not Target.Value <> "" Then
Application.ScreenUpdating = False
    Range("BP47:BZ80").Select
    Selection.Copy
    Range("BP83").Select
    Selection.PasteSpecial Paste:=xlPasteAllUsingSourceTheme, Operation:=xlNone _
        , SkipBlanks:=False, Transpose:=False
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Range("CM26").Select
    ActiveSheet.Paste
    Application.CutCopyMode = False
    Range("$BQ$45").Select
Application.ScreenUpdating = True
    End If
    End If
End Sub
Avatar billede store-morten Ekspert
18. august 2011 - 00:32 #9
Og så skal jeg lige læse ønsket og ikke kun din kode ;-)
1. Hvis celle BQ45 indeholder en værdi,
2. skal en simpel kopiering af et område  foretages. Der er formler bag disse celler, men kun værdierne skal indsættes.
3. medføre at celle BQ45 bliver tom.

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Range("$BQ$45"), Target) Is Nothing Then
      If Target.Value <> "" Then  '1 indeholder en værdi
Application.ScreenUpdating = False
    Range("BP47:BZ80").Select
    Selection.Copy
    Range("BP83").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False '2 kun værdierne
    Range("CM26").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False '2 kun værdierne
    Application.CutCopyMode = False
    Range("$BQ$45").Select
    Selection.ClearContents '3 bliver tom
Application.ScreenUpdating = True
    End If
    End If
End Sub
Avatar billede sus82 Nybegynder
18. august 2011 - 18:29 #10
Tak for svarene

Supertekst

Din kode pisker rundt. Jeg undrede mig over et par ting.

Dim flag As Boolean              '<--
Private Sub Worksheet_Change(ByVal Target As Range)

Burde det ikke være:

Private Sub Worksheet_Change(ByVal Target As Range)
Dim flag As Boolean

Jeg forstod heller ikke

flag = True              '<--
        Makro4
        flag = False            '<--

Apostrofferne. Er det meningen at jeg skal eksperimentere med hvilke udsagn der skal være falske/sande ?

Store Morten

Det er en god forklaring du kommer med, hvorfor den kører i ring. Man skulle jo bare mene at det er en gængs ting ved eventstyrede makroer, da det jo som regel er meningen at en event -ændring i arket- skal følges op med en handling, med mindre man blot ønsker at informere med en msg box.
Jeg har prøvet de forskellige kombinationer. Der sker ikke noget. Men pisker i det mindste ikke rundt.

Lad mig prøve at præcisere hvordan det er meningen at det skulle fungere.

Hvis celle BQ45 indeholder et eller andet- skal området BP47:BZ80
Kopieres og sættes ind, men kun som værdier, i et andet celleområde startende ved BP83. Dette nye område er tænkt som en mellemstation, hvor formlerne i BP47:BZ80 kan blive transformeret om til værdier. BP83 området skal så kopieres over i CM26, der er den egentlige destination. Grunden til mellemstationen, er at jeg vil undgå at ryge ind i noget cirkulær reference, og det kan man lettere undgå hvis formlerne allerede er transformeret om til værdier, fremfor at det først skal ske i CM26. Håber ikke at det bliver forvirrende nu. Når værdierne så er kommet over i CM26, vil andre formler evaluere området, og det vil bevirke at der ikke er nogen værdi i celle BQ45 (kun formler), hvorved at ingen handling foretage. Indtil en ny begivenhed starter, baseret på data der kommer ind fra nettet.

Håber at dette måske opklarer noget misforståelser.
Avatar billede store-morten Ekspert
18. august 2011 - 21:35 #11
Må vi se formlen i celle BQ45?
Avatar billede sus82 Nybegynder
18. august 2011 - 22:06 #12
Selvfølgelig, selvom det næppe giver meget mening:



=HVIS.FEJL(FORSKYDNING($BQ$23;MINDSTE($BP$23:$BP$43;1)-23;0);"")

Det jeg her prøver at finde ud af, er om der er en (eller flere) rækker med værdier i området. Det er ikke til at sige på forhånd, hvilke rækker, derfor forskydnings formlen.
Når disse værdier bliver indsat i CM26 forsvinder de, da de kun må forekomme en gang.
Avatar billede supertekst Ekspert
18. august 2011 - 23:34 #13
En erklæring på det sted får kendes "universelt" i denne alle Sub - men var ikke nødvendig her.

' <-- var kun markering af tilføjelser.

Ja koden gentages - men ikke udfører ingen "aktiviteter"
Avatar billede store-morten Ekspert
19. august 2011 - 15:57 #14
Prøv:

Private Sub Worksheet_Change(ByVal Target As Range)
      If Not Intersect(Range("BP47:BZ80"), Target) Is Nothing Then
      If Range("$BQ$45").Value <> "" Then
      Makro4
   
    End If
    End If
    End Sub
Avatar billede sus82 Nybegynder
19. august 2011 - 18:54 #15
Hej store-morten

Desværre, der sker ikke noget. Jeg overvejer faktisk, som alternativ løsning, at lade makro4 foregå på et andet ark for at undgå, forandringer i  "change" arket. Det vil jeg lige prøve imorgen, hvor der er mere tid og overskud.
Avatar billede store-morten Ekspert
19. august 2011 - 19:09 #16
sker ikke noget?

Jeg går ud fra at dine data som er i BP47:BZ80 er dem du ændre?

If Not Intersect(Range("BP47:BZ80"), Target) Is Nothing Then
Gør at Makro4 kaldes hvis der ændres i BP47:BZ80 og hvis celle BQ45 indeholder et eller andet.

Med din egen kode :-)

Det skulle modvirke at Makro4 starter igen når den kører.
Avatar billede store-morten Ekspert
19. august 2011 - 20:01 #17
Du har oplyst at BP47:BZ80 indeholder formler, min fejl ;-)

If Not Intersect(Range("BP47:BZ80"), Target) Is Nothing Then
Gør at Makro4 kaldes hvis der ændres i BP47:BZ80 og hvis celle BQ45 indeholder et eller andet.

Da dette område indeholder formler sker der nada...

Derfor skal du tilpasse til de celler du skriver i.
F.eks. som her Celle BK51:BK52 og bk53
If Not Intersect(Range("BK51:BK52", "bk53"), Target) Is Nothing Then

ikke indeholde område: BP83:BZ116 og CM26:CW59 så køres i ring.
Avatar billede store-morten Ekspert
20. august 2011 - 14:30 #18
Prøv denne:

Din egen kode med en tilføjelse:

Hvis celle BQ45 indeholder et eller andet- skal området BP47:BZ80
Kopieres og sættes ind, men kun som værdier, i et andet celleområde startende ved BP83

Koden gør at Makro4 ikke kaldes når mellemstationen BP83:BZ116 ændres.

Kopieres over i CM26
Koden gør at Makro4 ikke kaldes når den egentlige destination CM26:CW59 ændres.

Private Sub Worksheet_Change(ByVal Target As Range)
      If Intersect(Range("BP83:BZ116", "CM26:CW59"), Target) Is Nothing Then
      If Range("$BQ$45").Value <> "" Then
      Makro4
   
    End If
    End If
    End Sub

Sub Makro4()

    Range("BP47:BZ80").Select
    Selection.Copy
   
    Range("BP83").Select
    Selection.PasteSpecial Paste:=xlPasteAllUsingSourceTheme, Operation:=xlNone _
        , SkipBlanks:=False, Transpose:=False
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False
    Selection.Copy
   
    Range("CM26").Select
    ActiveSheet.Paste
   
End Sub
Avatar billede sus82 Nybegynder
20. august 2011 - 17:11 #19
Yes, der var den!

Godt gået, må jeg sige. Der er en lille og afgørende forskel om man i makro4 husker at skrive copy efter man har pastet i BP83, inden der indsættes i CM26.
Jeg er ved at køre en test, og denne kode gør at den kan stå og passe sig selv hele dagen, mens jeg er på arbejde. Vedholdenhed- stædighed kalder nogen det- betaler sig!.

Sender du et "svar"

Hilsen sus82
Avatar billede store-morten Ekspert
20. august 2011 - 17:53 #20
Det var dejligt :-)

Lige en mere til test:
Private Sub Worksheet_Change(ByVal Target As Range)
      If Intersect(Range("CM26:CW59"), Target) Is Nothing Then
      If Range("$BQ$45").Value <> "" Then
Application.ScreenUpdating = False
    Home = ActiveCell.Address
    HomeArk = ActiveSheet.Name

    Range("BP47:BZ80").Select
    Selection.Copy
    Range("CM26").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False

    Sheets(HomeArk).Select
    Range(Home).Select
Application.ScreenUpdating = True
    End If
    End If
    End Sub

Sammen bygget.
Bruger ikke mellemstation.
Gør at skærmen ikke 'flimmere' mens Makroen køre.
Og at den husker den celle der ændres i og ender der efter kørsel.
Avatar billede sus82 Nybegynder
21. august 2011 - 20:56 #21
store- morten

Du overgår dig selv. Denne var endnu bedre.

Tak for hjælpen!

Hilsen sus82
Avatar billede store-morten Ekspert
21. august 2011 - 22:48 #22
Velbekomme :-)
Du får lige en sidste version:
Private Sub Worksheet_Change(ByVal Target As Range)

On Error GoTo ErrorHandle

      If Intersect(Range("CM26:CW59"), Target) Is Nothing Then
      If Range("$BQ$45").Value <> "" Then
Application.ScreenUpdating = False
    Home = ActiveCell.Address
    HomeArk = ActiveSheet.Name

    Range("BP47:BZ80").Copy
    Range("CM26").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False

    Sheets(HomeArk).Select
    Range(Home).Select
   
BeforeExit:
Application.ScreenUpdating = True

Exit Sub
'Her havner vi ved programfejl
ErrorHandle:
Resume BeforeExit 'Dirigerer tilbage til BeforeExit

    End If
    End If
    End Sub

On Error GoTo ErrorHandle:
Hvis der mod forventning skulle opstå en fejl, vil ScreenUpdating altid blive slået til.
Og ved at springe 'select' over bliver Makroen hurtigere.

Tak for Point ;-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi har et stort udvalg af Excel kurser. Find lige det kursus der passer dig lige her.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester